const限定符:
const定义的变量必须初始化,可以在运行时初始化也可以在编译时初始化。
被const定义后的变量的值不能在被改变。
const的引用:
引用的类型必须与其所引用的类型一致。把引用绑定到const对象上,称为对常量的引用。
对 const的引用 简称为“常量引用”。常量引用不能被用来修改它所绑定的对象。
const int a = 10;
const int &ra = a;
ra = 20; //错误的,常量的引用不能修改绑定对象的值
int &rb = a; //错误的,试图让一个非常量引用一个常量,左右两边类型不匹配。
初始化和对const的引用:
引用的类型必须与其所引用对象的类型一致。但有种情况例外,下面再叙述。
允许为一个常量引用绑定非常量的对象、字面值、表达式。
int i = 10;
const int &r1 = i; //绑定对象
const int &r2 = 10; //绑定字面值
const int &r3 = r1 * 2; //绑定表达式
int &r4 = r1 * 2; //错误的,因为右边是const int类型与左边int类型不匹配)
例外情况就是在初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转成引用的类型即可。
例如:
double dval = 3.14;
const int &ri = dval;
常量引用ri绑定到dval上发的过程如下:
double dval = 3.14;
const int tmp = dval;
const int &ri = tmp;
编译器先创建一个临时变量,这个变量的类型与引用的类型一致。
然后这个引用在去绑定这个临时变量,而不是dval。
显然ri想通过绑定操作dval变量的内容,现在绑定在一个临时量上了,只能操作临时量的值,
这样做就没什么意义了。
常量引用仅对引用可参与的操作做出了限定,对于引用的对象本身是不是常量未作限定。
引用的对象如果不是常量,那可以通过非常量引用对引用的对象修改。否则,不能修改。
int a = 10;
int &ra = a;
const &ra1 = a;
ra = 20;
ra1 = 20; //错误的,ra1是一个常量引用
指针和const:
指向常量的指针不能用于改变其随之对象的值,想要存放常量对象的地址,只能使用指向常量的指针:
const int a = 10;
int *p = &a; //错误的,p是一个非常量的指针,左右两边类型不匹配;
const int *p1 = &a;
*p1 = 20; //错误的,p1不能修改指向对象的值
顶层const:表示指针本身是个常量。
int i = 10;
int *const p1 = &i; //p的内容不能修改
*p = 20; //是对的,指针所指的对象不是常量,可以修改
p1 = &a; //是错误的,指针是常量不能修改
底层const:表示指针所指的对象是一个常量。
int i = 10;
int a = 20;
const int *p2 = &i; //p所指向的内容不能修改
*p2 = 20; //是错误的,指针的对象是不 能修改
p2 = &c; //是对的,可以修改指针的指向,但不能修改指向的内容