顶层const:表示任意的对象是常量。
底层const:与指针和引用等复合类型的基本类型部分有关。
for example:
int i = 1; //i普通对象
const int j = 2; //j常量对象,不可改变j的值,属于顶层const
const int &k = j; //const的引用,属于底层const
int *const a1 = &i; // 常量指针,不可改变a1的值,属于顶层const
const int *a2 = &j; //指向常量的指针,允许改变a2的值,底层const
const int *const a3 = a2; //指向常量的常量指针,右边const为顶层const,左边const为底层const
当进行拷贝时,顶层const不受影响,而底层const却有限制。拷贝时,拷入和拷出的对象必须具有相同的底层const资格或者两个对象的数据类型必须可以相互转换(for example: a2 = &i; i可从int *转换成const int *)
for example:a=b(a代表等号左边的式子,b代表等号右边的式子)
若b为非底层const,a均可(for example:底层const/顶层const/普通)
若b为底层const,a必须有底层const(可包含顶层const)
常量表达式:值不会改变且在编译过程就能得到计算结果的表达式。
判断是否为常量表达式:由表达式数据类型及初始值共同考虑。
但有时很难分辨初始值是否为常量表达式,那么给const变量初始化时可能会出错。
C++11允许声明变量为constexpr类型,这样编译器可验证变量是否为常量表达式。
for example:
constexpr int m = 2; //2是常量表达式
constexpr int n = m+1; //m+1是常量表达式
constexpr int p = size(); //只有当size是constexpr函数(编译时即可得到计算结果),才是正确语句
建议:一般来说,若认定变量是一个常量表达式,把其声明成constexpr类型。