简单理解就是:加了const就变成了只读,这适用于我们不想让程序改变我们变量的值的情况。
const初始化
- const对象一旦创建就无法改变,所以const对象必须初始化,初始化可以使用复杂的表达式。
- 默认情况下,const对象仅在文件内有效
如果有多个文件需要共享同一变量,则使用extern关键字解决这一问题,
//file1.cc定义并初始化了一个常量,该常量能被其他文件访问
extern const int bufSize = func();
//file1.h头文件
extern const int bufSize;//与file1.cc中定义的bufSize是同一个
//作用是:指明bufSize()并非本我呢见所独有,它的定义将在别的地方出现
const和引用
类似于指针,减少内存开销
引用类型都要和与之绑定的对象严格匹配,而且,引用只能绑定到对象上,而不能与某个字面值或者某个表达式的计算结果绑定到一起。
错误示例:
int & refVal4 = 10;//错误,引用类型的初始值必须是一个对象
double dval = 3.14;
int & refVal5 = dval;//错误,引用了欸新的初始值必须是int型对象
例外情况:
- 初始化常量引用时允许用任意表达式作为初始值
int i = 42;
const int &r1 = i;
const int &r2 = 42;//正确
const int &r3 = r1 * 2;//正确
int & r4 = r1 * 2;//错误,r4是普通变量引用,不允许使用表达式结果绑定
//实际上是绑定到了一个值为r1*2的临时变量,这样子引用没啥意义,编译器干脆将这种行为归为非法
const和指针
int a = 10;
const int * p = &a;//p指向的只读
int * const q = &a;//q为只读变量
顶层const:指针本身是个常量
底层const:指针所指对象是个常量
cosntptr和常量表达式
常量表达式是指不会改变并且在编译过程就能得到计算结果的表达式
const int max_files = 20;//是
const int limit = max_files + 1;//是
int staff_size = 27;//不是,是普通变量
const int sz = get_size();//不是
允许将变量声明为constptr类型以便由编译器来验证变量的值是否是一个常量表达式。声明为constptr的变量一定是一个不变量,而且必须用常量表达式初始化。
constptr int mf = 20;//20是常量表达式
constptr int limit = mf + 1;//mf + 1是常量表达式
constptr int sz = size();//只有size是一个constptr函数时才是一条正确的声明语句
const和函数
- const用于普通函数参数
常见的拷贝构造函数中,参数传递为只读引用,引用的目的是防止无限递归调用拷贝构造函数,只读的作用是防止在函数体内部修改引用参数t。
class Test{
public:
Test(){}
Test(const Test & t){};
};
operator重载中同样如此,使用const的目的是防止参数被修改
class Widget{
Widget & operator=(const Widget & ths){
...
return *this;
}
}
- const用于this指针
非静态成员函数都有一个默认参数this指针,在函数参数列表后边加const其实意味者给this指针加const,表示this指向的对象是只读的,不可以修改成员变量。
例:
#include <iostream>
using namespace std;
template<class T>
class Test{
public:
Test(){}
~Test(){}
void setTest(T const& a)
{
x = a;
}
T getTest() const
{
//x++; //因为有const,所以不能改变x的值
return x;
}
private:
T x;
};
int main()
{
Test<int> te;
int a;
cin >> a;
te.setTest(a);
cout << te.getTest();
return 0;
}
上例中,getTest()后边加const,代表this所指的成员变量在getTest()中是只读的。