基本概念:常量限定符,表明被其修饰的变量只能被访问,不能被修改,也就是只读。
用法可分为以下几类
修饰基本数据类型
1、修饰一般常量及数组:在类型说明符前或后加const,表明这些常量不可被修改。定义时必须初始化。
2、修饰指针变量:
①如果const位于星号的左侧,则const就是用来修饰指针所指向的变量,即指针指向为常量;
可以不先初始化,因为指针内容是常量,但指针本身不是常量
不能通过指针改变所指向的值
int b=400;
const int * a =&b;//但值本身可通过自己修改;指针也可以指向别的值
等价于
const int *a;
a=&b;
②如果const位于星号的右侧,const就是修饰指针本身,即指针本身是常量。
定义时必须初始化
指针只能永远指向这个变量(不能进行加减或其他导致指针值改变的计算操作)
但指向的变量可变,可通过指针改变该变量的值。
3、修饰引用:引用不能被更新;
在函数中使用
参数const:通常用于参数为指针或引用的情况。
返回值const:修饰返回值为对象本身(非引用和指针)的情况多用于二目操作符重载函数并产生新对象的时候。
在类中使用
1、修饰成员变量
表明该成员常量不可被修改; 只能在初始化列表中赋值; 只有const成员函数能访问
2、修饰成员函数
表明const成员函数不修改对象的成员变量
3、修饰类对象/对象指针/对象引用
表明其中的任何成员都不可被修改; 只能调用const成员函数
小结:
1)const成员函数
可以访问非const对象的非const数据成员、const数据成员,
可以访问const对象内的所有数据成员;
2)非const成员函数
可以访问非const对象的非const数据成员、const数据成员
不可以访问const对象的任意数据成员;
3)const修饰变量必须初始化化,只发生在,该变量被const的情况下。
const和#define的区别
二者都可用于定义常量,但区别主要有的三点:
①const常量有类型,会进行类型安全检查;#define无类型,不会进行安全检查;
②const编译运行时使用;#define预处理时使用;
③const占用内存(可以是堆,也可以是栈);#define只展开,不占内存,用多少次,展开多少次。
volatile和mutable
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,系统总是重新从它所在的内存读取数据,即使它前面的指令刚刚从该处读取过数据,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
可以和const一起使用,原因在于const只能起到告诉编译器不要试图去修改它
volatile变量的几个例子:
①并行设备的硬件寄存器(如:状态寄存器)
② 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
③ 多线程应用中被几个任务共享的变量
mutable关键字在C++中,如果需要在const成员函数里修改数据成员,可用mutable修饰这个数据成员。