Const与指针:
int a (1024);
const int * p1(&a);//p1可以指向不同的对象,对象的内容只能读不可写
int * const p2(&a);//p1可以指向唯一的对象,对象的内容可读可写
const int * p3(&a);//同上
const int * const p4(&a);//p1可以指向唯一的对象,对象的内容只能读不可写
int const *const p5(&a);//同上
Const与多级指针:
int *b(&a); int *c(&a);
const int **P1(&b);//P1可以指向不同的指针,指向的指针可以指向不同的对象,对象的内容只能读不能写
int *const*P2(&b);//P2可以指向不同的指针,指向的指针指向唯一的对象,对象的内容可读可写
int **const P3(&b);//P3指向唯一的指针,指向的指针可以指向不同的对象,对象的内容可读可写
const int *const*P4(&b);//P4可以指向不同的指针,指向的指针指向唯一的对象,对象的内容只可读不可写
const int **const P5(&b);//P5必须指向唯一的指针,指向的指针可以指向不同的对象,对象的内容只能读不能写
int *const*const P6(&b);//P6必须指向唯一的指针,指向的指针指向唯一的对象,对象的内容可读可写
const与引用:
(用 const 修饰的引用时为底层引用)
变量可以初始化引用类型,常量(任意表达式,只要其结果能转化成所对应的引用类型即可)可以初始化引用类型(&)和常量引用(const 类型 &)。但常量不能初始化引用类型。
①对于常量可以初始化常量引用类型,一般编译器都会为其分配一个临时量,将这个值保存到临时量中,然后让引用指向这个临时量。
int main(void) { const int &b = 1024.1024; //mov dword ptr[ebp - 18h], 400h //lea eax, [ebp - 18h] //mov dword ptr[b], eax return 0; }
| int main(void) { const int temp = 1024.1024; //mov dword ptr[temp], 400h const int &b = temp; //lea eax, [temp] //mov dword ptr[b], eax return 0; }
|
当编译时,编译器会将const int &b = 1024.1024;编译成两句 const int temp = b;const int &ri = temp;其中temp 是一个临时变量,他用来缓存表达式的求值结果。所以b与临时变量绑定在一起的。同时给b赋值一个变量也是合法的这样就省去了添加临时变量这一步。
即便是 赋值右值也为 引用类型 相对应的类型,也要调用临时量,所以只要是常量 赋值给常量引用,就要调用临时量
const int &a = 12;
const int &b = 4+3;
②对于变量可以初始化常量引用类型来说,除了变量与引用类型相同之外,其他情况也要建立一个临时量。
double D = 1024.1024;
const int &a = D;
//优化成
const int temp = D;
const int &a = temp;
解释 为什么常量不能初始化引用类型,或者,为什么引用类型必须与引用对象类型一致?
如果引用类型不是常量,那么这个引用类型就执行和上述操作一样,这个引用类型将与一个临时变量绑定,由于是引用类型,在后续操作中就会对其取值或者重写操作,然而对一个临时变量进行这些操作是无意义的,所以c++标准将这种行为归为非法。
Const与指针的引用复合类型:
int b(1024), *p1(&b);
int * &rp1(p1);//rp1指向一个 int*类型的对象
const int* p2(&b);
const int* &rp2(p2);//rp2指向一个 const int*类型的对象
//const int* &rp2(p1);//error p1为 int* 而rp2指向一个 const int*类型的对象
const int* &rp2( const int* (p1) );
int*const p3(&b);
int* const &rp3(p3);//rp3指向一个 int*const类型的对象
// int* const &rp2(p1);//error p1为 int* 而rp3指向一个 int*const类型的对象
int* const &rp3( int* const(p1));