1.顶层const和底层const
顶层const:本身是一个常量
底层const:所指的对象是一个常量
2.例子
int *const p1 = &i;
const修饰p1,p1本身是一个const,所以这个const是顶层const
const int ci = 42;
const修饰ci,ci本身是一个const,顶层
const int *p2 = &ci;
const修饰*p2,修饰的是p2所指的对象,所以是一个底层const
const int *const p3 = p2;
第一个const修饰*const p3,为const p3所指的对象,所以为底层
第二个const修饰p3,则p3本身为const,这个const为顶层const
3.常量表达式constexpr
限定符constexpr只对指针有效,与指针所指的对象无关
const int *p = nullptr;
const修饰p所指的对象,所以为底层const
constexpr int *q = nullptr;
由于constexpr只修饰指针,所以q为一个常量,故为顶层const
4.类型别名typedef
typedef char *pstring;
const pstring cstr = 0;
const修饰cstr,cstr本事为一个常量,所以为一个顶层const
不能将类型别名替换成原来的样子
const char *cstr = 0;
此时const修饰cstr所指的对象,这时的const是一个底层const,而用类型别名所定义的是一个顶层const