1. const 限定符
const把变量进行限定,定义为常量,必须初始化;const变量默认情况仅在文件内有效;
因此,只在一个文件内定义const,而在其它多个文件中声明并使用;
const int val = 100;
任何视图对val进行赋值的操作都将引发错误;
编译器会找到所有用到 val 的地方,然后用100将其替换;
//file.cpp定义并初始化一个const常量
extern const int val = 100;
//file.h头文件声明
extern const int val;
指明 val 并非本文件独有;多个文件共享const对象;
2. const的引用
可以将引用绑定到const对象上,这就称为常量引用
**作用:**常量引用主要用来修饰形参,防止误操作
被常量的引用不能用作修改它所绑定的对象:
const int val = 100;
const int &ref = val; //正确,引用及其对应的对象都是常量
ref = 200; //错误,ref是对常量的引用,不能更改
int &ref2 = val; //错误, ref2为非常量引用,val为常量
const引用类型必须和所引用的对象类型一致,其中一个例外:
在初始化常量引用时允许用任意表达式作为初始值,只要该表达式结果能转化成引用的类型即可;
int val = 100;
const int &ref = val; //正确,允许将const int& 绑定到一个普通int对象;
const int &ref2 = 200; //正确, 为常量引用
double val = 10.99;
const int &ref = val;
//二者类型不同,此时编译器做如下操作:
const int temp = val;
const int &ref = temp;
生成的temp称为临时量对象
3. const 和指针
与引用一样,指针也可以指向常量或非常量;
常量指针
const int val = 100;
int *ptr = &val; // 错误:ptr为一个普通指针
const int *ptr2 = &val // 正确:ptr为一个常量指针
*ptr2 = 200; // 错误:不能给*ptr赋值
另外一个例子:
int val = 100;
const int *ptr = val;
这个做法是正确的,只是不能通过 *ptr改变val的值;
总结:和常量引用一样,并没有规定说常量指针所指向的对象必须是一个常量,常量指针仅仅要求不能通过该指针改变其指向对象的值,而对象的值可以通过其它途径改变
指针常量
由于指针本身就是对象,因此也可以用const对指针进行限定,这样指针的指向就不能再改变了;
指针常量必须初始化,之后就无法改变了;
int val = 100;
int *const ptr = &val; // ptr将始终指向val
const double pi = 3.14;
const double *const ptr2 = &pi // ptr2是一个指向常量对象的指针常量
指向常量对象的指针常量,不论是其指向的对象值还是ptr2自己的存储地址都不能改变
试着运行了一下代码,常量指针可以不进行初始化,而指针常量必须初始化
4. 常量表达式
基本要求:
- 值不会改变;
- 在编译阶段就能得到计算结果;
const int val = 100; //是常量表达式
const int val2 = val + 10; //是常量表达式
int staff = 20; //不是,普通int型
const int size = getSize(); //虽然size值不会变,但结果需要到运行阶段才能得到
constexpr变量
在复杂系统中,很难分辨初始值是否为常量表达式。C++11新标准规定,允许将变量声明为constexpr类型由编译器来验证是否为常量表达式;
constexpr int val = 100; //合法
constexpr int val2 = val + 10; //合法
constexpr int sz = getSize(); //只有当getSize()被定义为constexpr函数时才合法
新标准允许定义一种特殊的constexpr函数,使得编译阶段就能获得函数结果;
一般来说,如果认定变量是常量表达式,就把它声明为constexpr类型
一个constexpr指针的初始值必须是nullptr或者0,或者是存储于某个固定地址的对象;
因此,一般来说,constexpr指针不能指向函数体内定义的变量,因为非固定地址;
指针和constexpr
constexpr定义的指针只对指针有效,与指针所指对象无关;
const int *p = nullptr //p是一个指向整型常量的指针
constexpr int *p2 = nullptr //p2是一个指向整数的指针常量
与其它指针常量类似,constexpr指针既可以指向常量,也可以指向非常量;
int j = 1;
constexpr int i = 2;
constexpr const int *p = &i; //p为指向整型常量的指针常量
constexpr int p2 = &j; //p2为指针常量,指向整数j