详解C/C++中const限定符总结

2020-02-19 12:00:48王振洲

const限定符

const是一种限定符,被const所限定的变量其值不可以被改变。

const的初始化

由于const一旦创建其值就不能够被改变,所以我们必须对其进行初始化

const int a;//错误,const变量必须进行初始化!
const int b=10;//正确,编译时初始化
const int c=get_size();//正确,运行时初始化

相同类型的变量相互初始化时,不论变量是否被const限定我们都可以进行随意的相互拷贝。因为在拷贝过程中我们只会用到等式右边变量的右值属性,无须在意其是否可以改变。

int m = 5;
const int n = m;
int j = n;

const与指针

顶层const与底层const

对于指针来说,由于其指向另一片内存的特点,有三种不同的const情况,即:

    指向常量的指针(const int *) 常量指针(int * const) 指向常量的常量指针(const int *const)

我们一般称符合第一种情况的为具有底层const属性。

符合第二种情况的为具有顶层const属性。

第三种情况兼而有之。

关于带有const的指针的相互赋值(或者初始化)问题

顶层const并不会影响变量间的相互拷贝(原因是顶层const只保证自身的值不会改变,const没有改变自身的变量类型,在拷贝时只是使用该类型的右值)。 如果等号右边是底层const,那么等号左边必须保证为相同的底层const(或者等号右边的类型可以转换成等号左边的类型),否者表达式无法通过编译。

关于底层与顶层const的一些想法

const的底层与顶层属性似乎只在指针上存在。但是c++primer中有这样的代码和注释:

const int ci=1,&cr=ci;
auto b=ci;//b是一个整数(ci的顶层const特性被忽略掉了)
auto c=cr;//c是一个整数(cr是ci的别名,ci本身是一个顶层const)

这段代码是为了说明auto说明符一般会忽略掉顶层const的特性,在注释中明确写着 ci本身是一个顶层const 。

这也与我的看法一致,底层与顶层const实际上并不是指针所特有的,只要是不能改变对象自身的对象都具有顶层const,而不能改变自己所指向的对象的对象都具有底层const。

从这个角度看,引用实际上自带顶层const。

底层const的隐式转换

上面提到,只有在等号右边和等号左边的类型具有相同的底层const属性,才可以进行赋值或者初始化。

然而有些时候等号右边可能并不具有和等号左边一致的底层const却依然可以成立,这是因为等号右边的类型发生了隐式转换从而具有了和等号左边类型相同底层const属性。

例如:

int i=5;
int *p=&i;
const int *cp=p//int*隐式转换称为了const int*

为什么int 转换成const int 被设定为合法的呢,因为在将int 转换为const int 的过程中用户的权限变小了,在这一转换过程中并不会使程序变得不可靠。