理清 C++ 中顶层 const 和底层 const 的概念,感觉理解起来有些混乱。
具体讲解看的是《C++ Primer》。
核心概念
顶层 const (top-level const):对象本身是常量
底层 const (low-level const):指针/引用指向的对象是常量
具体例子
1. 顶层 const 的例子
1 2 3
| int a = 10; const int b = 20; int *const p1 = &a;
|
特点:
- 对象本身的值不能改变
- 对于指针:指针的指向不能改变,但指向的内容可以改变
1 2 3 4
| int a = 10, b = 20; int *const p = &a;
*p = 30;
|
2. 底层 const 的例子
1 2 3 4
| int a = 10; const int *p1 = &a; int const *p2 = &a; const int &r = a;
|
特点:
- 指针/引用指向的对象是常量
- 指针的指向可以改变,但不能通过指针修改指向的对象
1 2 3 4
| int a = 10, b = 20; const int *p = &a; p = &b;
|
3. 同时包含的情况
1 2
| const int *const p = &a;
|
记忆技巧
方法1:看 const 的位置
1 2 3
| int *const p; const int *p; int const *p;
|
方法2:从右向左读
1 2
| int *const p; const int *p;
|
实际应用中的区别
1. 拷贝操作的限制
1 2 3 4 5 6 7 8 9
| int a = 10; const int b = 20;
int c = b;
const int *p1 = &a; int *p2 = p1; const int *p3 = p1;
|
2. 函数重载
1 2 3 4 5
| void func(int *p); void func(const int *p);
void func(int p); void func(const int p);
|
这里需要用函数值传递仔细说明一下:
const不会改变参数的类型,因此不能作为函数重载的依据。会忽略掉顶层const
函数进行传参时,传的都是值的副本,对副本是否加const,不会改变参数类型。
1 2
| void fun1(int x); void fun1(const int x);//报错
|
Redundant ‘fun1’ declaration [readability-redundant-declaration]
E:\UnrealWorld\project\Learncpp\Learncpp\main.cpp:5:6: note: previously declared here
3. 引用的情况
引用天生就是”顶层 const”(因为引用一旦绑定就不能改变),所以我们只关心底层 const:
1 2 3
| int a = 10; int &r1 = a; const int &r2 = a;
|
总结
类型 |
示例 |
const 类型 |
什么不能改变 |
常量整数 |
const int a |
顶层 const |
a 的值 |
常量指针 |
int *const p |
顶层 const |
p 的指向 |
指向常量的指针 |
const int *p |
底层 const |
通过 p 修改指向的对象 |
常量引用 |
const int &r |
底层 const |
通过 r 修改绑定的对象 |
核心区别:
- 顶层 const:我本身是常量
- 底层 const:我指向/引用的对象是常量