C++ primer const 限定符

const 限定符

const int bufSize = 512;

// 限定后不能改变!

const int k; // 不对!!!k是一个未经初始化的常量!

int i = 42;

const int ci = i;

int j = ci; // ci只有被改变时才会发挥作用,作为其他操作值仍然起作用!

const 只在文件中起作用!!,如果想全局起作用需要extern

const 的引用

可以把引用绑定到其他对象上,我们称之对常量的引用(reference to const)

对常量的引用,不能被用作修改它所绑定的对象

const int ci = 1024;

const int &ri = ci;

ri = 42; // 错误!!!ri是对常量的引用

int &r2 = ci; // 错误!!,试图让一个非常量引用指向了一个常量对象

引用的类型必须和所引用的对象的类型一致, 但是有两个例外,

1 :

int i =42;

const int &r1 = i; // 正确!!

const int &r2 = 42; // 正确!!

const int &r3 = r1*2; // 正确!!

int &r4 = r1*2; // 错误!!r4是一个普通的非常量的引用!

double val = 3.14;

const int &ri = dval;

此处的ri 引用了一个int型的数,对ri 的操作应该是整数运算,但是dval是一个double,因此,其实编译器是做了如下操作!

const int temp = dval;

const int &ri = temp;

在这种情况下,ri绑定了一个临时量对象!

int i = 42;

int &ri = i;

const int &r2 = i;

r1 = 0;

r2 = 0; // 错误!!!,因为r2是个常量引用!!,不允许通过r2 修改i 的值,

2.4.2 指针和const

指向常量的指针(pointer to const ) 不能用于改变其所指对象的值,要想存放常量的地址,只能使用指向常量的指针

const double pi = 3.14;

double *ptr = π // 错误!!,ptr是一个普通指针,

const double *cptr = π

cptr = 42; // 错误!不能给cptr 赋值

指针类型必须与其指向的对象类型一致,但是有两个例外,

1 允许指向常量的指针,指向非常量

double dval = 3.14;

cptr = &dval ; // 可以,但是不允许通过cptr改变dval 的值,(但是可以通过其他途径改变)

const 指针!

指针是对象,而引用不是,因此就像其他对象类型一样,允许把指针本身定义为常量!!!

常量指针,必须初始化,而且一旦初始化,则它的值也就不能改变了

int errNumb = 0;

int * const curErr = & errNumb; // 指针只能一直指向 errNumb

const double pi = 3.14159;

const double *const pip = π // pip 是一个指向常量对象的常量指针

从右往左读!!!

2.4.3 顶层 const

用顶层(top - level const )表示指针本身就是个常量

用底层( low- level const ) 表示指针所指的对象是一个常量

执行copy 操作的时候,常量是顶层,几乎没有影响

但是底层const 的限制不容忽略!!

拷贝和拷出的对象必须具有相同的底层const 资格,或者两个对象类型必须能相互转换!一般来说,非常量能转换成常量,反之不行!

2.4.4 constexpr 和常量表达式

常量表达式(const expression) 是指 值不会改变,并且在编译过程中就能得到计算结果的表达式。显然字面值属于常量表达式

const int max_files = 20; // 是常量表达式

const int limit = max_file +1; // 是常量表达式

int staff_size = 27; // 不是常量表达式!首先就不是常量!!

const int sz = get_size(); //不是!因为sz 的值,只有在运行过程中才能获取到!!

C++11 新标准规定,允许将变量声明为 constexpr 类型,以便由编译器来验证变量的值,是否是一个常量表达式!

constexpr int sz = size(); 只有当size是一个constexpr函数时,这才是一条正确的声明语句!

字面值类型:

尽管指针和引用都能定义成为constexpr ,但它们的初始值却受到严格限制,一个constexpr 指针的初始值必须是nullptr 或者0,或者存储与某个固定地址的对象!

posted @ 2020-11-14 21:29  UXCcccc  阅读(67)  评论(0)    收藏  举报