1.顶层const和底层const
const修饰的对象本身是常量,则为顶层const,否则为底层const
如:
const int a=10; //a是int常量,顶层const
int *const b=nullptr; //b为指向int 类型的常量指针,顶层const
const int *c=nullptr; //c为指向const int 类型的指针,指针c所指对象为常量,指针c本身不是常量,底层const
2.注意点
下面两种情况下,p是常量指针,而不是指向常量的指针,等价于char *const p=nullptr,而不是const char *p=nullptr;
- typedef char* type;
const type p=nullptr;
- constexpr char *p=nullptr;
3.对const的引用
可以用任意类型的表达式作为初始值,但即使用非const变量初始化,也不能通过引用名修改绑定对象的值
int i=42;
const int &a=i; //ok,但不能通过a修改i的值
const int &b=42; //ok
const int &c=a*2; //ok
但普通变量不能对const引用
const int a=1;
int &b=1; //error
4.指向const的指针(底层const)
和引用一样,指向const类型的指针可以用同类型的const和非const初始化
如:
const int i=10;
int j=10;
const int *a=&i; //ok
a=&j; //ok
但指向非const的指针只能用同类型的非const初始化
如:
const int i=10;
int j=10;
int *p=&j; //ok
p=&i; //error
5.常指针(顶层const)
int i=10;
const int j=10;
int k=10;
int *const p=&i; //ok
*p=12; //ok,p指向的对象不是常量,可以改变
*p=j; //error,p是指向int型的,而不是指向const int类型的
p=&k; //error,p本身是常量,其值不能改变