关于关键字const用法的若干总结
关键字 const 的首要功能是通过类型检查帮助编译器查找程序中(更多)的错误;其次,借助编译器强迫代码符合最初的设计。在设计可复用代码时,const显得非常重要。
1.关于常量修饰符的含义
1.1 例子
char* p="Hello";
char const* p="Hello";
char* const p="Hello";
char const* const p="Hello";
1.2 说明
区分以上各语句的正确含义。
参见文章:http://www.cnblogs.com/holynn/archive/2009/10/18/1585675.html
2.设计函数原型时,对那些不可能被修改的参数用const修饰
2.1 例子
void blockCopy(void* pDest, const void* pSrc, size_t length);
2.2 原因
今后无意(有意)对blockCopy()函数的任何修改要对pSrc所指向的数据进行写操作,就会引起编译错误,从而保证后继开发者遵循最初的设计。
3. 关于常量成员函数
3.1 说明
常量成员函数是指函数体不会对任何成员(包括基类成员,但不包括静态成员)进行修改的成员函数。其函数声明以关键字const结尾。常量函数隐含的this指针指向常量对象,但因为this隐含,无法将const修饰符加上,只能放在结尾。由此可以推出以下原则:
■若成员函数在设计时不修改任何成员,则应该定义为常量成员函数。这样常量对象和非常量对象都可以使用该函数。
■常量成员函数和同名同参(显式)的非常量成员函数可以重载,这是因为他们的第一个(this)参数类型不同。
这一点常被人忽视,但很有用:比如类需要在多线程中使用,其成员函数要上锁,不论该函数要修改某些成员还是只是读取成员(你在读的同时,别人可能正在修改)。但常量对象是不能上锁的,因为锁本身也是成员,上锁是修改锁成员的动作,在常量对象中是不能做的。
那么,是不是常量对象在多线程中就是不能用了呢?显然不是。其实你只要再提供(重载)一个常量成员函数,其中不需要上锁,直接读取成员做相应的操作就可以了。这是因为在这个新提供的成员函数中,this指向常量对象,不用担心有人修改,上锁就没有必要了。
3.2 例子
class MyClass_T
{
public:
int func(int aParam)const; //相当于int func(MyClass_T* const this,int aParam);
int func(int aParam); //重载。相当于 int func(MyClass_T* this,int aParam);
}
4.不要让常量成员函数修改程序的状态
4.1 说明
意思是说,常量成员函数不要修改成员、静态成员、全局变量、其他对象,以及所有会会造成该对象或程序状态改变的东西。
4.2 原因
造成程序状态改变的成员函数不是绝对意义上的常量成员函数,虽然不一定违反C++语法,但语义有问题,不太符合大多数人对常量成员函数的预期。
5. 不要将常量成员函数强制转换成非常量
原因:如果要这么做,先想一想该常量是否根本就应该是变量,否则给出足够的理由。要防止想要利用常量的优点,却将变量的缺点带进来。
以上总结引用之《C++编码规范》,稍作修改。