场景1
double dval = 3.14;
const int &r1 = dval;//允许
int &r2 = dval;//不允许
int &r3 = r1*2;//错误,不能通过非常量引用指向常量
场景2
const double pi = 3.14;
double *ptr = pi;//错误,ptr存在修改pi的风险
const double *cptr1 = π//底层const
const int ci = 0;//顶层const
double *const cptr2 = pi;//顶层const
场景3
constexpr int mf = 20;
constexpr int limit = mf + 1;
constexpr int sz = size();//只有当size本身是一个constexpr函数才正确
constexpr int *np = nullptr;//常量指针
分析1:double类型赋值给int,编译器产生一个中间值temp = 3,r2为temp别名无用,所以编译器不允许。而r1有const修饰不用于改变dval值,所以允许存在。
分析2:顶层const表示变量本身是一个常量
底层const表示指针所指向的对象是一个常量
分析3:变量一定是一个常量,必须用常量表达式初始化