C++程序中尽可能使用const

const用在变量声明和定义式中,用以为变量提供语义约束,说明该变量是不可以改变的,可用以修饰全局变量、局部变量、静态变量、类成员变量以及定义常量指针和指针常量。

const修饰STL迭代器

STL(标准模板库)的迭代器的作用类似于指针,声明迭代器为const,类似与定义一个常量指针,可以改变迭代器指向的变量的值,但不能将迭代器指向不同的变量。如果希望迭代器是一个指针常量,可以使用const_iterator类型定义迭代器,它声明指向的变量的内容不可改变,但迭代器本身的指向是可以改变的。

/*****************************************
 * stl_iterator.cpp                      *
 *                                       *
 * const修饰标准模板库中的迭代器         *
 *****************************************/

#include <iostream>
#include <vector>

int main()
{
  std::vector<int> vec(10);
  const std::vector<int>::iterator iter = vec.begin();

  *iter = 10;
  iter++;/*错误*/
  std::cout<<"第一个元素为"<<*iter<<"\n";

  std::vector<int>::const_iterator citer = vec.begin();
  *citer = 20;/*错误*/
  citer++;
  std::cout<<"第二个元素为"<<*citer<<std::endl;

  return 0;
}

const迭代器

注释掉错误代码,编译运行。
const迭代器运行正常

函数返回const

函数返回常量值可以降低因函数的错误使用而造成的意外。

/****************************************
 * const_function_return.cpp            *
 *                                      *
 * 函数返回const值                      *
 ****************************************/

#include <iostream>

class Rational
{
private:
  int x;

public:
  Rational(int x)
  {
    this->x = x;
  }

public:
  int GetX() const{return x;}

};

const Rational operator* (const Rational& lhs, const Rational& rhs)
{
  return Rational(lhs.GetX() * rhs.GetX());
}

int main()
{
  Rational a(3);
  Rational b(4);

  Rational c = a * b;

  std::cout<<"c中的x为"<<c.GetX()<<std::endl;

  return 0;
}

const函数返回值

如果在函数返回时不指定const,则下面的程序也是允许的.

/****************************************
 * const_function_return.cpp            *
 *                                      *
 * 函数返回const值                      *
 ****************************************/

#include <iostream>

class Rational
{
private:
  int x;

public:
  Rational(int x)
  {
    this->x = x;
  }

public:
  int GetX() const{return x;}

};

Rational operator* (const Rational& lhs, const Rational& rhs)
{
  return Rational(lhs.GetX() * rhs.GetX());
}

int main()
{
  Rational a(3);
  Rational b(4);

  Rational c(10);
  (a * b) = c;

  std::cout<<"a中的x为"<<a.GetX()<<std::endl;
  std::cout<<"b中的x为"<<b.GetX()<<std::endl;
  std::cout<<"c中的x为"<<c.GetX()<<std::endl;

  return 0;
}

取消返回const

而这样的表达式不符合基本运算规则,而且没有影响。出现这种情况很可能是在输入时候将==错输入为=

const成员函数

const成员函数可作用于const对象。
C++中,const成员函数和相应的非const成员函数是可以重载的。

const成员函数中无法修改它的成员变量,若确实要在const成员函数中修改成员变量,在需要类的成员变量的定义式中使用mutable修饰符。

/****************************************
 * const_mutable.cpp                    *
 *                                      *
 * Const成员函数修改对象属性            *
 ****************************************/

#include <iostream>

class Number
{
private:
  int x;
public:
  Number(int _x)
  {
    x = _x;
  }

public:
  int GetX() const
  {
    x = 2 * x;
    return x;
  }

  void PrintX()
  {
    std::cout<<"x = "<<x<<std::endl;
  }
};
int main()
{
  Number a(10);
  a.GetX();
  a.PrintX();
  return 0;
}

不能修改类变量值

修改x的定义式为:

class Number
{
private:
  mutable int x;
  ...

则可以在const成员函数GetX中修改x变量的值,程序正常运行。
正常运行结果

在非const成员函数中调用const成员函数避免代码重复

/****************************************
 * nonconst_call_const.cpp              *
 *                                      *
 * 在非const成员函数中调用const成员函数 *
 * 避免代码重复                         *
 ****************************************/

#include <iostream>

class TextBlock
{
private:
  const char *pText;
public:
  TextBlock(const char *_pText)
  {
    pText = _pText;
  }

public:
  const char& operator[](std::size_t position) const
  {
    return pText[position];
  }

  char& operator[](std::size_t position)
  {
    return const_cast<char&>(static_cast<const TextBlock&>(*this)[position]);
  }
};
int main()
{
  TextBlock a("Hello World");
  const TextBlock b("World");

  std::cout<<"a的第一个字符为"<<a[0]<<std::endl;
  std::cout<<"b的第一个字符为"<<b[0]<<std::endl;
  return 0;
}

例子中非const的下标重载运算符调用const下标重载运算符,实现字符访问。涉及两类转换,第一类是从Text&const Text&的静态转换,使用static_cast,一类是返回值由const char&转换为const使用const_cast去处常量标志。

non-const调用const

参考文献

  1. Scott Meyers著,侯捷译. Effective C++中文版. 电子工业出版社. 2012.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值