1.顶层const与底层const的定义
const修饰的变量不可以改变,那么他就是顶层const,如:
const int a = 10;
那么,对于
const int *const p = new int(10);
第二个const就是顶层const,因为他修饰的是p;第一个const是底层const,因为他修饰的不是p,而是p所指向的。
引用的const一定是底层const,如:
const int &a = 10;
2.注意事项
当执行对象拷贝操作时,常量的顶层const不受什么影响,底层const必须一致
例子:
#include <iostream>
#include <string>
int main() {
// part 1
// 定义一个const变量,表示a不能被改变了
const int a = 10;
//令b = a,只拷贝了指,const属性并没有被拷贝
int b = a;
// part 2
const int *const p = new int(10);
int *p1 = p;
int *const p2 = p;
const int *p3 = p;
// part 3
int *p4 = &a;
// part 4
const int &r1 = 20;
int &r2 = a;
int &r3 = r1;
return 0;
}
part 1
对于此代码第一部分,const int a = 10这句话其实和int a = 10是一样的,因为顶层const没有影响,可以忽略,因此可以直接执行拷贝操作,即int b = a;不会报错。
part 2
对于第二部分,首先定义了一个const int *const p = new int(10),由于顶层const可忽略,所以变成const int *p = new int(10);所以在第二行就会报错,报错信息为
就是因为int *p的类型不等于const int *p,同理,第三行也会报相同的错误,第四行才是正确的。
part 3
对于第三部分int *p3 = &a;乍一看,a的定义变成了int a = 10,那么这句话似乎是对的,但是当对a取地址时,&a变成了指向a的地址,那么他就变成了底层const,因此,代码应该修改为:const int *p3 = &a.
part 4
关于引用的const:
- 引用不是对象,不进行拷贝,不满足上面的原则(蓝字部分)
- 常量引用如果在左侧,右侧可以接任何东西
eg:
int &r1 = 40;会报错,因为a是一个引用,而引用是一个对象的别名,而40只是一个临时的数据,他不是一个对象,所以这句话是错误的;那么,如果代码改为const int &r1 = 40,这句话就不会报错
- 非常量引用 = 常量, 报错
eg:
首先对于代码int &r4 = a,这里的a是一个const常量,值为10,说明a不可以被改变, 而r4这个引用是a的别名,他的类型不是const,说明可以使用别名对a的值进行改变,所以会报错。