《C++Primer》笔记之【const限定符】
0.const的含义
定义:将一个变量定义为常量,使其不能再改变。
注意:const对象一旦创建就不能再改变,所以const必须初始化。
//错误用法,const对象一旦创建就不能再被修改
const int a=0;
a=100;
const int a; // 错误,未初始化const对象
const的初始化
可以用非常量对象来初始化常量对象,也可以用常量对象来初始化非常量对象。
//非常量对象来初始化常量对象
int i=42;
const int a=i;
//常量对象来初始化非常量对象
const int a=100;
int j=a;
1.const与引用
1.1 引用
定义
- 《C++primer》对引用的定义为:为对象起别名,引用也可看作与它初始化的对象的一种绑定。
- 引用一旦定义完成,就将和他的初始化对象一直绑定在一起。
- 对引用进行的所有操作都是在与之绑定的对象上进行的。
int ival=1024;
int &refVal=ival;
1.2 对常量的引用
对常量的引用:reference to const,即const ElemType &name =xxx;
若引用的对象是const,则要求引用也必须是const
const int ci=1024;
const int &r1=ci;
int &r2=ci;//错误,因为ci是const,表示不能改变ci的值,对r2进行的操作就是对ci的操作,若r2不是const,表示可以改变r2,但实际上r2不可以改变
const引用的初始化
与普通的引用不同,const引用的引用对象可以与它类型不同
int i=42;
const int &r1=i; //正确
const int &r2=42; //正确
const int &r3=2*r1; //正确
int &r4=r1; //错误
const引用的引用对象可以不是const
//r1是对i的引用,r1不可以改变,故不能通过r1来修改i的值
int i=42;
const int &r1=i;
r1=0; //错误,r1是常量,不可改变
2.const与指针
2.1 指向常量的指针
指向常量的指针(pointer to const):不能改变所指对象的值,但是可以改变所指的对象。
指向常量的指针所指的对象:对象可以是常量,也可以不是常量。
若所指对象为const,则要求指针也必须为const。
const int i = 100;
const int j = 200;
int *ptr1 = &i; //错误,ptr1是普通指针,应该是指向常量的指针
const int *ptr2 = &i; //正确,ptr2是指向常量i的指针
*ptr2 = 101; //错误,不能改变所指对象的值
ptr2 = &j; //正确,可以改变所指的对象
2.2 const指针(常量指针)
常量指针:将指针定义为常量。必须初始化,一旦初始化完毕,就不能再改变它的值(存放在指针中的地址,也可以说是指针所指的那个对象)。用*const
来表示常量指针。
int a = 0;
int *const ptr1 = &a; //ptr1是常量指针,指向a,且不会再指向别的元素
const int b = 0;
const int *const ptr2 = &b; //从右往左读,*const表示ptr2是常量指针,前面的const表示其所指的对象是一个常量
3. 顶层const和底层const
- 对于指针而言:顶层const表示指针本身是常量,底层const表示指针所指的对象是常量
- 对于引用而言:只有底层const,因为引用自身根本就不是一个对象,更无引用本身是常量这一定义
- 对于其他数据类型:如算数类型、类,都是顶层const
执行对象的拷贝操作时,常量是顶层const还是底层const差别明显。
- 若是顶层const,则无影响。
- 若是底层const,则要求拷入和拷出的对象必须具有相同的底层const资格,或者两个对象的数据类型必须能转换,非常量可以转换成常量,反之则不行。