const限定符
const最常用的就是定义常量。const对象一旦创建后其值就不能再改变,所以const对象必须初始化。初始值可以是任意复杂的表达式。
const int i = get_size(); //正确:运行时初始化
const int j = 42; //正确:编译时初始化
const int k; //错误:k是一个未经初始化的常量
默认状态下,const对象仅在文件内有效,如果想要在多个文件之间共享某一个const对象,必须在变量的定义之前添加extern关键字。
//file_1.cc定义并初始化了一个常量,该常量能被其他文件访问
extern const int bufSize = fcn();
//file_1.h头文件
extern const int bufSize; //与file_1.cc中定义的bufSize是同一个
const的引用
可以把引用绑定到const对象上,就像绑定到其他对象上一样,我们称之为对常量的引用(简称为常量引用)。对常量的引用不能被用作修改它所所绑定的对象。
const int ci = 1024;
const int &r1 = ci; //正确: 引用及其对应的对象都是常量
r1 = 42; //错误:r1是对常量的引用
int &r2 = ci; //错误:试图让一个非常量引用指向一个常量对象
常量引用允许绑定非常量的对象、字面值、甚至是一般表达式。
当常量引用绑定const对象时,绑定的对象不会变(也不能变);但是,当常量引用绑定非const对象时,绑定的对象可以发生改变(虽然不允许通过该绑定的常量引用去修改绑定对象的值,但是绑定对象的值仍然允许通过其他途径修改)。
int i = 42;
int &r1 = i; //引用r1绑定对象i;
const int &r2 = i; //r2也绑定到非const对象,但是不允许通过r2修改i的值
r1 = 0; //r1并非常量引用,i的值可以修改,此时r2绑定的值已经修改
r2 = 0; //错误:r2是一个常量引用
cout << r2 << endl; //0 已经被r1修改,下同
cout << i << endl; //0
const与指针
参见 指针常量和常量指针的区别,看看你们的理解跟我的一样嘛??
const其他用法小结:
const最常用的就是定义常量,除此之外,它还可以修饰函数的参数、返回值和函数的定义体。
1. const修饰函数的参数
如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const 修饰,否则该参数将失去输出功能。
const 只能修饰输入参数:
如果输入参数采用“指针传递”,那么加const 修饰可以防止意外地改动该指针,起到保护作用。
将“const &”修饰输入参数的用法总结如下:
(1)对于非内部数据类型的输入参数,应该将“值传递”的方式改为“const 引用传递”,目的是提高效率。例如将void Func(A a) 改为void Func(const A &a)。
(2)对于内部数据类型的输入参数,不要将“值传递”的方式改为“const 引用传递”。否则既达不到提高效率的目的,又降低了函数的可理解性。例如void Func(int x) 不应该改为void Func(const int &x)。
2. const 修饰函数的返回值
如果给以“指针传递”方式的函数返回值加const 修饰,那么函数返回值(即指针)的内容不能被修改,该返回值只能被赋给加const 修饰的同类型指针。例如函数
const char * GetString(void);
如下语句将出现编译错误:
char *str = GetString();
正确的用法是
const char *str = GetString();
如果返回值不是内部数据类型,将函数A GetA(void) 改写为const A & GetA(void)的确能提高效率。但此时千万千万要小心,一定要搞清楚函数究竟是想返回一个对象的“拷贝”还是仅返回“别名”就可以了,否则程序会出错。
函数返回值采用“引用传递”的场合并不多,这种方式一般只出现在类的赋值函数中,目的是为了实现链式表达。
例如:
class A
{
A & operate = (const A &other); // 赋值函数
};
A a, b, c; // a, b, c 为A 的对象
a = b = c; // 正常的链式赋值
(a = b) = c; // 不正常的链式赋值,但合法
如果将赋值函数的返回值加const 修饰,那么该返回值的内容不允许被改动。上例中,语句 a = b = c 仍然正确,但是语句 (a = b) = c 则是非法的。
3. const修饰成员函数
关于Const函数的几点规则:
a. const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数.
b. const对象的成员是不可修改的,然而const对象通过指针维护的对象却是可以修改的.
c. const成员函数不可以修改对象的数据,不管对象是否具有const性质.它在编译时,以是否修改成员数据为依据,进行检查.
d. 然而加上mutable修饰符的数据成员,对于任何情况下通过任何手段都可修改,自然此时的const成员函数是可以修改它的