C++中const用来把变量声明为固定值,即不允许改变const变量的值,但是可以进行读操作。这里对const数值变量大家应该比较了解,就带过,着重写一下对指针和对引用的作用。以及top-level const和low-level const。
一、const数值变量
对于内置算术类型的变量,声明为const之后是不允许改变变量的值的
const int i=0;
const double pi=3.14;
i=2;//非法!不允许改变
也因为这样,const变量在声明的时候必须进行初始化。不能有如下的:
const int a;//错误,要进行初始化
二、const引用
引用已经初始化绑定给一个变量之后绑定是无法改变的,所以对引用的const主要在于能否用引用来改变绑定变量的值。
(1)用const引用绑定一个const变量值的时候,原值无法改变,也不能通过引用改变变量的值。
(2)用const引用绑定一个非const变量值的时候,原值可以改变,但是不能通过引用改变变量的值。
const int i=3; const int &r=i; i=2;//错误 r=2;//错误
int i=3;
const int &r=i;
i=2;//正确
r=2;//错误
(3)不能用非const绑定一个const变量。
const int i=3;
int &r=i;//错误
对于上面三点其实很好理解,C++一个变量的类型决定了能对它进行的一系列操作,当为const的时候就是不能改变他的值。所以第二点中const引用说明了引用的类型是const,所以是不能改变它所引用的值的,而这与被引用的值是否是const没有关系。但是在第三点中原值为const,当用非const引用来引用它之后可能通过引用来改变它的值,这样就会相冲突,所以被拒绝了,是错误的。
(4)当引用为const时,可以把他能够转换成自己类型的值给引用
double pi=3.14;
const int &r=p;//正确,并且r=3
const int &r2=3;//正确,r2=3
这里需要说明的是r并没有引用pi,相反在进行这个操作的时候,分配了专门的内存来存放r所引用的位置,并且值为3,类型为整形。r值到达这块内存的唯一接口。
三、const指针
有三种格式
int i=3;
const int *p1=&i;//不可以通过指针改变i
int *const p2=&i;//不可以改变指针的指向
const int *const p3=&i;//既不可以改变i,也不可以改变指向
(1)将指针指向的类型声明为const,是不能通过指针间接改变所指的值的。
(2)将指针的类型声明为const,这种是实际意义的const指针,即指针的指向一经初始化之后不能改变。
(3)两者都为const时,既不能改变指向,也不能间接改变被指向的值。
理解这个声明只需要和上一篇里面一样的方法,从右向左确定类型,对于const int *const p3=&i,首先是*const,说明它是指针,并且是const的,其次是int,说明它指向的是int类型的值,最后是const,说明不能通过这个指针改变指向的int值。
最后,关于top-level const和low-level const:
C++中把直接对变量内存单元中的const限制称为top-level const,即无法改变内存中的值。把对间接指向和引用的值的const限制称为low-level const,即无法改变所指向和所引用的值。在两个变量进行赋值操作时,必须要有同样的level才可以,具体法则是这样的:
(1)top-level可以忽略掉
int i=0;//non-level
int *const p=&i;//top-level
(2)low-level不可以忽略
因为p1是low-level而p2不是,所以不能进行p2=p1的操作。int i=0; const int *p1=&i; int *p2=p1;//错误
(3)在右边的low-level可以转换为non-level而反过来不可以
因为p2具有low-level而p1没有,所以可以p2=p1而不能p1=p2。int i=0; int *p1=&i; const int *p2=p1;//ok p1=p2;//wrong