const 关键字
-
默认情况下 const 对象仅在文件内有效
如果我们不希望编译器为每个文件分别生产独立的变量,也就是仅在一个文件中定义 const 对象,而在多个文件中声明并且使用它。解决方案:对于 const 变量不管是声明还是定义都添加
extern
关键字,即:
// file.cpp
extern const int buffSize = fcn();
// file.h
extern const int buffSize; // 与file.cpp 中定义的 buffSize是同一个
- const 类型的引用
int main()
{
double dval = 3.14;
const int& ri = dval; // 可以
// int& rd = dval; // 不可以
}
问题来了,为什么上述代码中const类型的可以,而去掉const类型的代码就不行了?
这是因为,dval 是 double 类型,需要经过类型转换转换为一个 int 类型的临时量,临时量再指向rd。然而我们这样写的最初目的一般是去修改dval的值,但是这里rd并不指向dval,会产生歧义(或者说对临时量的值进行修改是没有什么意义的),所以C++禁止这种写法。而上面的带有const
修饰的 ri 本身就不可以修改所指向的值,所以也就没有这个问题了。
- const 和 指针
const double dd = 3.33;
// double* ptr = ⅆ // 不可以
const double* cptr = ⅆ // 可以, cptr 是一个 指向常量的指针
// *cptr = 42.0; // 不可以
cptr = &dval; // 可以
通过上面的代码可以得出, 指向常量的指针 不能改变它指向对象的值,但是可以改变指向的对象。和常量引用一样 它仅仅提供该对象不会通过该指针被修改,是否该对象能否通过其他途径修改并不关心。
除此之外,与引用不同的是,指针是C++的一种对象而引用不是,所以同其他对象一样指针也允许被定为常量。被称为 ** 常量指针 ** 和其他的const对象一样,常量指针一样必须初始化。
int qq = 0;
int * const ccptr = &qq; // ccptr将一直指向qq
int i = 1;
// ccptr = &i; // 不可以,修改常量指针指向的对象
*ccptr = 111; // 可以
const int * const cccptr = &i; // 指向常量对象的常量指针,无法修改指向的对象的值也无法修改指针的指向
- constexpr 关键字
constexpr int *q = &i;
// 等价于 常量指针
int * const q = &i;
// 而不是指向常量的指针
const int *q = &i;