顶层Const和底层Const

发布时间 2023-09-10 11:03:25作者: timeMachine331

说的都是指针类型,只有指针有这种说法

顶层const:         int * const p = a     表明指针本身的值(指向)是常量无法修改,也无法转化为int *类型。即便是const_cast试图去掉这样的顶层const属性也不可以。

底层const:         int const * p = a.    表明指针指向的对象是常量,无法通过指针进行解引用去修改对象的值,但是可以通过const cast 去除底层const然后拷贝构造一个指向普通类型的指针,用这个指针去修改值。

 

const还分两种,全局作用域下的const跟在某个函数体内的const。全局const也是声明了只有在当前源文件内才可以使用这个const,同时它会被存储在常量区,程序只有读和执行的权限没有写权限,而函数中的const是存在函数的栈帧里的,可以通过对其取地址构造指针之后解引用。

 

全局作用域下的const变量可以在一个头文件里定义,然后其他cpp文件引用她都没问题,每一个cpp源文件都会有自己独立的一份,这个常量区里头的不允许修改。

而非const类型的变量在头文件里定义的花就会有重复定义的问题,需要使用extern表明是在其他文件中被定义,而在此文件中无法再初始化了。

 

赋值问题
const
int ci = 0; int &a = ci; 报错,引用类型必须与被引用的对象类型一致 但是有例外的特殊情况 可以把常量引用绑定到非常量上 只要基本类型一致并且能转为常量引用比如 int i = 0; const int &a = i; const int ci = 0; int *a = &ci;报错非常量指针无法指向常量。 int i = 0; const int *a = &i; 底层const 指针常量可以指向非常量,无法通过a修改i

如果是顶层const,那么解引用之后能否修改对象的值,取决于对象是常量还是非常量。
int a = 0;
int *const ai = &a;
*ai = 1;没问题

const int ap = 0;
int* const api = ≈
*api = 1;报错

至于如果试图修改顶层const的值(指向)那么直接报错。

 

关于引用中的const,全部都是底层const,即对象的值是否能改变,因为所有引用在定义时都已经绑定了对象之后所以不存在顶层const

 

 

关于顶层const和底层const的不同拷贝操作。

如果是顶层const,那它的指向是无法改变的,可以被赋值

以下两句都没问题 注意因为它有顶层const

const int * const p3 = p2;p3顶层const,p2没有

p2 = p3 。p2没有 p3有 也没问题执行之后p2还是没有顶层const。只是给了指向。

 

这块还是有点模糊