条款 03:尽可能使用const
1、请记住
- 将某些东西声明为const可帮助编译器侦测出错误用法。const可被施加于任何作用域内的对象、函数参数、函数返回类型、成员函数本体。
- 编译器强制实施bitwise constness,但你编写程序时应该使用“概念上的常量性”(conceptual constness)。
- 当const和non-const成员函数有着实质等价实现时,令non-const版本调用const版本可避免代码重复
2、原因
const允许指定一个语义约束(指定一个“不该被改动”的对象),编译器会强制实施这项约束。
他允许你告诉编译器和其他程序员某值应该保持不变。
3、const用法
3.1、在classes外部修饰global或namespace作用域中的常量
3.2、修饰文件、函数、或区块作用域中被声明为static的对象
3.3修饰classes内部的static和non-static成员变量
3.4、修饰指针
可以指出指针自身、指针所指之物,或者两者都(或都不)是const:
char greeting[] = "Hello";
char* p = greeting; //non-const pointer,non-const data
const char* p = greeting; //non-const pointer,const data
char* const p = greeting; //const pointer,non-const data
const char* const p = greeting; //const pointer,const data
const在星号左边,表示被指物是常量
const在星号右边,表示指针自身是常量
const出现在星号两边,表示被指物和指针两个都是常量
3.5、如果被指物是常量
下面两个函数接受的参数是一样的
void f1(const Widget* pw);//f1获得一个指针,指向一个常量的(不变的)Widget对象
void f2(Widget const* pw);//f2也是
不同的人,习惯不一样,但两种写法意义相同。
3.6、声明迭代器为const
表示这个迭代器不得不指向不同的东西,但他指向的东西的值是可以改变的。
如果希望迭代器所指向的东西不可以改动,需要的是const_iterator:
std::vector<int>vec;
....
const std::vector<int>::iterator iter =vec.begin();//iter的作用像个T*const
*iter = 10;//没问题,改变iter所指之物
std::vector<int>::const_iterator cIter = vec.begin();//cIter的作用像个const T*
//*cIter = 10; 错误!*cIter是const
++cIter;//没问题,改变cIter
在一个函数声明式内,const可以和函数返回值、各参数、函数自身(如果是成员函数)产生关联。