Effective c++: const的使用
精髓:尽可能的使用const
语法上的问题——const修饰指针和迭代器
指针
如果关键字const出现在星号左边,表示被指物是常量;
如果出现在星号右边,表示指针自身是常量;
如果出现在星号两边,表示被指物和指针两者都是常量。
其中const写在下图两个位置时等价
迭代器
const与函数
const修饰函数的参数和返回值
修饰参数
确保传入的参数不会被改变,多用于修饰一个常引用。
例如:
1 | void print(const TextBlock & ctb); |
修饰返回值
1.防止误操作修改了返回值
例如将 (a + b) == c的判断错误的写成了(a + b) = c,此时若返回值被const修饰,则可以提示出错误。
2.返回常引用时,防止调用者通过常引用修改原值
例如:
1 | const char& operator[] (std: :size t position) const{} |
1 | const TextBlock ctb ("world"); |
const成员函数
为什么要有const成员函数?
const用来标识函数是否会改动对象的值
改善C++程序效率的一个根本办法是以 pass byreference-to-const方式传递对象,而此技术可行的前提是,我们有const成员函数可用来处理取得(并经修饰而成)的const对象。
实质
标识的实质是将成员函数的this指针标识为const
从上图中可以看出,this指针前面有了const进行修饰。
另外const成员函数虽然不能改变对象的值,但是可以改变传入的引用,指针所指向的值,因为不涉及到this指针。
常量性不同的函数的重载
对于同一种函数,常有const和non-const两种形式的重载,例如
对于两种const而言,可能存在如下方这样代码重合度非常高的情况,会造成代码冗余
我们当然可以把重合的代码写进对象内部的一个private函数中,然后让两个函数分别调用。但是这样也还是会造成一些代码冗余。
另一种方案就是对this指针进行转型。用non-const函数的转型后的this指针来调用const函数。并且对返回值解除const限制。
代码如下:
关于两种const概念
bitwise constness
主张成员函数只有在不更改对象的任何成员变量的时候才可以说是const,也就是不更改对象内的任何一个比特。
编译器所执行的即为此种概念下的const。
但也会有许多成员函数虽然不够具有const性质,但也能通过编译器的bitwise测试
例如对象内只存储了一个指针,成员函数不修改对象内存储指针的指向,但可以修改指针指向的值
logical constness
主张成员函数可以修改它所处理对象内的某些bits,只要客户端侦测不出来就可以
如何做?
编译器强制实施bitwise constness,但编写程序时应该使用”概念上的常量性“。
那么什么时候会需要解决这一问题呢?
例如:
1 | class Test |
对于如下这样一个类。希望可以用它来进行输出,输出的过程不更改函数内部对象的值,自然可以把输出函数设置为const。
但是假如我们需要统计一下函数输出了多少次。
1 | class Test |
修改为上方所示,如果不加mutable,自然会报错。但是我们又需要告诉调用者调用这个函数与对象的状态无关,所以const自然还是保留比较好。
这个时候我们就可以借助mutable关键字来标注times变量。
计数器times被mutable修饰,那么它就可以突破const的限制,在被const修饰的函数里面也能被修改。
从而实现逻辑上的常量性。