【C++】指针与const
最近学习到C++指针与const这一块,被常量指针和指针常量搞得有点乱,书上也没有解释得很详细,于是决定自己进行一些试验,将结果与个人的理解记录下来,以供大家参考。
1.常量指针
常量指针,也称 指向常量的指针,顾名思义,其所指向的对象是一个常量(但后面我们会说到其实并非如此)。
反过来,一个常量,如果要定义指向他的指针,则必须使用指向常量的指针!
原因:const 声明的常量不允许修改,如果可以用非常量指针指向常量,则常量将可以通过此指针修改,这是不合理的
const int i = 101; // 定义一个常量
int *p = &i; // 报错
const int *cp = &i; // 正确
但是!指向常量的指针,也可以指向一个非常量对象!!!这就是指针类型必须与指向类型严格相同的一个典型特例!
int i = 101;
const int *cp = &i; // 正确
所以,我认为应该这样理解 常量指针:不允许通过此指针修改其指向的对象。
言下之意就是说:常量指针所指向的对象(非常量),依旧可以通过其他途径修改,并且常量指针也能够同步这一修改
#include <iostream>
using namespace std;
int main() {
int i = 1;
int *p = &i;
const int *cp = &i;
*p = 101; // 如果通过*cp进行修改则会报错
std::cout << "*p: " << *p << ", *cp: " << *cp << std::endl;
system("pause");
}
执行输出
*p: 101, *cp: 101
2.指针常量
大家都知道,指针和引用的不同点之一就是——指针自身也是一个对象。
既然是对象,那么指针自身也可以被定为一个常量。
而指针存放的是其所指向对象的地址,所以指针被定为常量的后果就是,他存放的地址不能被改变,他 永远只能指向一个对象!
这样又对应了指针和引用的另一个不同点——指针在其生命周期内可以指向多个不同的对象。指针常量显然断绝了其三心二意的念想~
int i = 1;
int j = 2;
int *const p = &i;
p = &j; // 报错
3.指向常量的指针常量
希望大家已经完全理解了上面的内容,下面可能要开始打架了......
不过如果牢记上面划线的定义,我相信还是能把常量指针和指针常量很好地区分开的~
指向常量的指针常量,按照上文的理解,首先他只能永远指向一个对象,其次你不能通过他修改对象。
这就有点像提供了一个对象的 Getter(有点的吧...?)
换一个角度想,我们还能得到以下一些想法:
- 常量指针在其生命周期内可以指向不同的对象
- 指针常量允许使用者使用他对其所指向的对象进行修改
- 如果想让一个指针永远指向一个常量,我们必须使用指向常量的指针常量
4.顶层/底层const
顶层const:表示对象是一个常量
底层const:表示复合类型指向的对象是一个常量
// 顶层const示例
const int ci =1;
int i = 101;
int *const cp = &i;
const int *const ccp = cp; // 靠右的是顶层const
// 底层const示例
const int ci = 101; // 这个是顶层const
const int *p = &ci;
const int &r = ci;
const int *const ccp = p; // 靠左的是底层const
当执行拷贝(赋值)操作时,顶层const几乎不受限制,而=两边的对象则要求拥有相同的底层const资格!一般来说,非常量可以转化成常量,而反过来则不行!
int i = 1;
const int ci = 101;
const int &r = ci;
int *const p = &i;
const int *cp = &ci;
const int *const ccp = cp;
cp = ccp; // 正确:顶层const无影响
int *p2 = p3; // 错误:底层const资格不一致
cp = &i; // 正确:int* 能转成 const int*
梳理了一下,自己也清晰了不少,希望对大家也有所帮助~
参考书目:Primer C++ 第五版(中文)