const限定符
- const限定符用于定义一个常量
- const对象在定义时必须被初始化
- 默认情况下,const对象仅在文件内有效。如果在不同的文件下出现了同名的const变量,则视作在文件中单独定义的独立变量。如果想在不同的文件中使用同一个从上图变量,则需要在声明和定义前都添加extern关键字。
//file1.cpp中定义一个const变量
extern const int A = 3;
//file1.h中声明
extern const int A; - 另外在C语言和C++中const含义是有区别的,在C++中const修饰的变量就是一个常量,即不能通过任何方式来改变它的值;而在C语言中,const修饰后的变量本质上仍然是一个变量,只是不能通过变量名来改变它的值,但是可以通过指针这样的方式来修改。
const和引用
- 可以吧引用绑定在const对象上,称为常量引用,不过要注意引用需用const修饰。
const int ci = 10;
const int &r1 = ci; //正确
r1 = 3; //错误,r1是对常量的引用,自然常量的值是不能被修改的
int r2 = ci; //错误,非常量引用是不能指向常量的 - 引用的类型必须和其所引用的对象类型一致,不过有两个例外
- 一个const引用可能指向非const的对象,常量引用仅对引用可参与的操作做了限定,而对引用的变量是否const没有限制。
int i = 12;
const int &ri = i; //正确
ri = 23; //错误,r2是一个常量引用,不能通过它来修改i的值 - 初始化常量引用时允许用任意表达式作为初始值,只要该表达式的结果能转换为引用的类型即可。
int i = 2;
const int &r1 = i * 2; //正确
const int &r2 = r1 + 3; //正确
const double &r3 = r1; //正确
const double &r4 = r3/3; //正确
int &r5 = i + 2 //错误
这个初始化的过程是这样的:表达式首先被计算后,结果值被赋给了一个临时变量,然后将常量引用和该临时变量绑定。这也就解释了为什么不能将一个非const引用用表达式初始化,因为可以通过普通引用来修改变量的值
,但是修改一个临时变量的值又有什么意义呢?所以这样的操作就被定为非法了。
- 一个const引用可能指向非const的对象,常量引用仅对引用可参与的操作做了限定,而对引用的变量是否const没有限制。
const和指针
指向常量的指针
指向常量的指针表示不能通过该指针来改变所指向对象的值,不过和常量引用类似的,指向常量的指针也有如下两个特点:- 指向常量的指针既可以指向const对象,也可以指向非const对象,const仅仅只是限制了指针的操作。
- 普通指针不能指向const对象。
另外注意指向常量的指针不是必须初始化的,并且它所指向的对象是可以改变的。
const int a = 23;
int b = 12;
const int *p;
p = &a;
p = &b;
int *p2 = &a; //错误,普通指针不能指向const对象const指针
- 指针本身也可以被定义为常量,在声明中将*放在const表示该指针是一个const指针。
- 自然地,const指针作为一个常量也必须被初始化,并且之后它的值(所指向的地址)就不能被改变了。
- 指针本身是常量并不意味这指针所指向的对象的值不能被改变,这完全取决于所指对象的类型。
const int a = 1;
int b = 2;
int *const p1 = &b; //正确
p1 = &a; //错误,p的指向不能被改变了
*p1 = 3; //正确,p所指的是普通变量,它的值可以被修改
const int *const p2 = &a; //正确,这是一个指向常量的const指针
//它的指向不能被改变,并且而不能通过它来改变所指对象的值