[C++]顶层const和底层const
——摘自 C++ primer p57
1. 引入
指针,是一个对象,它又可以指向另外一个对象。
因此,指针是不是常量和指针指向的对象是不是一个常量是两个相互独立的问题。
由此,引入名词
顶层const(top-level const): 表示指针本身是一个常量。
底层const(low-level const): 表示指针所指的对象是一个常量。
2. 一般化
顶层const表示任意的对象是常量。
底层const则与指针和引用等复合类型的基本类型部分有关
tips:
指针类型既可以是顶层const也可以是底层const。
3. 例子
```
int i = 0;
int *const p1 = &i; // 不能改变p1的值, 这是一个顶层const 顶层const: 表示指针本身是一个常量。p1 是一个常量
const int ci = 42; // 不能改变ci的值, 这是一个顶层const
const int *p2 = &ci; // 能改变p2的值, 这是一个底层const 底层const: 表示指针所指的对象是一个常量。ci 是一个常量
const int *const p3 = p2; // const p3 这是一个顶层const(对象 p3), const int * 是底层const (对象 ci)
const int &r = ci; // 用于声明引用的const都是底层const
```
4. 关于执行对象拷贝操作时,常量是顶层const和底层const的区别
顶层const
执行对象拷贝操作时, 顶层const 不受什么影响:
int i = 0;
const int ci = 42; // 不能改变ci的值, 这是一个顶层const
i = ci; // 正确: 拷贝ci的值,ci是一个顶层const, 对此操作无影响
const int *p2 = &ci; // 能改变p2的值, 这是一个底层const 底层const: 表示指针所指的对象是一个常量。ci 是一个常量
const int *const p3 = p2; // const p3 这是一个顶层const(对象 p3), const int * 是底层const (对象 ci)
p2 = p3; // 正确:p2和p3指向的对象类型相同,都是int类型,p3顶层const的部分不影响
?执行拷贝操作(i = ci;)并不会改变拷贝对象(const int ci)的值,因此,拷入(p2)和拷出(p3)的对象是否是常量都没什么关系。(whether the object copied from or copied into is const) ( 例如: const int *const p3 = p2;)
底层const
执行对象拷贝操作时,拷入和拷出的对象必须具有相同的底层const资格,
或者两个对象的数据类型必须能够转换。
一般来说,非常量可以转换成常量,反之不行:
const int ci = 42;
const int *p2 = &ci;
const int *const p3 = p2; // const p3 这是一个顶层const(对象 p3), const int * 是底层const (对象 ci)
int *p = p3; // p3包含底层const的定义,而p没有
p2 = p3; // 正确:p2 和 p3 都是底层const
// 非常量可以转换成常量
p2 = &i; // 正确, 非常量可以转换成常量 int * 可以转换为 const int *
int &r = ci; //错误:普通的 int & 不能绑定到 int 常量上
const int &r2 = i; // 正确:const int & 可以绑定到 普通的 int 上
浙公网安备 33010602011771号