const限定符总是让人很头疼,下面讲解一下几个比较容易混淆的概念:
- 对常量的引用(常量引用):
一般情况下,引用的类型要与其所引用的对象的类型一致,其中的例外情况就是,当初始化常量引用时,允许用任意表达式作为初始值,只要改表达式能转换成引用的类型即可。
const int i = 1;
const int &ri = i;
int i = 42;
const int &r1 = i;
const int &r2 = 42;
- 指向常量的指针
和引用类似,一般情况下,指针的类型应该与其指向的对象的类型一致,但是允许一个指向常量的指针指向一个非常量对象。
const int i = 4;
const int *cptr = &i;
int a = 1;
cptr = &a;
- 常量指针
由于指针本身就是一个对象,因此可以定义一个指针为常量指针,必须被初始化。当常量指针指向一个对象时,那么这个指针永远只能指向这个对象,但是被指向的对象的值能否改变,取决于被指向的对象本身是否是一个常量。
int i = 1;
int *const cp = &i;//cp永远指向i,
i = 2;//由于i是非常量,其值可以改变
const int c = 2;
const int *const p = &c;//p是一个指向常量的常量指针
c = 1;//错误,c为常量,其值不能被改变
p = &i;//错误,p是一个常量的指针,其指向不能改变
- 顶层const与底层const
顶层const表示指针本身就是一个常量,而底层const表示指针所指的对象是一个常量。
int i = 0;
int *const pi = &i;//pi的值不能被改变,pi为顶层const
const int ci = 42;//ci是一个int类型的常量,值不能被改变,为顶层const
const int *p2 = &ci;//p2是一个指向常量的指针,p2的值可以改变,所以p2为底层const
const int *const p3 = p2;//靠右的const是顶层const,靠左的const是底层const
const int &r = ci;//用于声明引用的const都是底层const