Eccective C++ 条款3 尽可能使用const
C++ const 允许指定一个语义约束,编译器会强制实施这个约束,允许程序员告诉编译器某值是保持不变的。如果在编程中确实有某个值保持不变,就应该明确使用const,这样可以获得编译器的帮助。
const 出现在星号左边,表示被指物是常量,如果出现在星号右边,表示指针自身是常量。
如果同时出现在星号左右两边,表示被指物和指针都是常量。
如果被指物是常量,const写在类型前或者写在类型后、星号前,这两种写法意义相同。
声明STL迭代器为const 就像声明指针为const一样(即声明T * const指针 ),表示迭代器不得指向不同的东西,
但指的东西的值可以改变。若希望指的东西不可被改动(即模拟const T * ),需要const_iterator .
令函数返回一个常量值,可以降低用户错误造成的意外,例如:
将operator *的回传值声明为const可以预防那个没意思的赋值动作。
至于const 参数,没有什么特别新颖的概念。
const成员函数作用:1.使得class接口容易被理解,得知哪个函数可以改对象内容,而哪些函数不可以。
2.使得操作const对象成为可能。
两个成员函数如果只是常量性不同,可以被重载。这是C++的重要特性。
只要重载operator[] 并对不同的版本给与不同的返回类型,就可以令const和non-const TextBlock获得不同的处理。
non-const operator [] 的返回类型是个 reference to char ,不是char 。如果只返回char ,那么 下面句子无法通过编译
tb[0]='x';
因为如果函数饭返回内置类型那么改动函数返回值从来都不合法,纵使合法,C++以by value 返回对象这一事实意味着改动的
是tb.text[0]的副本,而不是tb.text[0]自身。
这里面编译没有任何错误:但是这里面创建了一个常量对象并设以某值,并且只调用const函数,但最终还是改变了对象的值。
上面的解决方法:利用C++的一个与const相关的摆动场:mutable(可变的)。mutable释放掉non-stastic 成员的约束。
在const和非const成员函数中避免重复:
假设在const和非const函数中都要进行相同的检验工作, 导致代码重复。即使把重复部分单独出来写成函数,还是重复了函数调用,return语句等的重复
解决方法是,使其中一个operator[] 调用另一个,这就促使将常量性转除。
上例中const做了非const该做的一切,唯一不同是返回类型多了一个const资格修饰,这种情况下将返回值的const转除是安全的。
上例中将*this从原始类型TextBlock&转型为const TextBlock&,然后从返回值中移除const。
上例的反向做法会冒这样一个风险,承诺不改动的对象被改动了。所以const调用非const是错误行为。