2024-7-13
这里特别是关于多文件的const在C++ primer中简单的带过去了,实际上理解起来需要用到其他像编译、链接的知识。
特点:
- 限定变量只读,因此使用时必须初始化
- 在多文件中共享const对象,该变量的定义和声明都添加extern关键字。对于const的实现,实际上是由编译器在编译过程中将const变量替换成对应的值,因此在多文件中,如果共享一个const对象,由于const对象都需要进行初始化,将造成重复定义的问题。
// file_1.cpp 定义并初始化了一个常量,该常量能被其他文件访问
extern const int a = GetValue();
// file_1.h 头文件中声明常量 a
extern const int a; // 此时的 a 与 file_1.cpp 中定义的 a 就是同一个
这个时候自然考虑到只在一个文件进行定义,在其他文件进行声明,思考以下例子1
//a.cpp
#include <iostream>
extern const int i;
int main() {
std::cout<<i;
return 0;
}
//b.cpp
const int i;
这里会报错未定义 i 。
实际上关键在于了解extern关键字的作用:改变const变量的默认链接属性
//fileA.cpp
extern const int i = 42; // 定义变量i并修改默认链接属性为全局可见
//fileB.cpp
extern const int i; // 声明这个变量在其他文件进行了定义
在例子1中,a.cpp中声明了 a 定义在其他文件中,然而b.cpp中对 i 的定义对a.cpp是不可见的。
但我们还要考虑编译顺序的影响,考虑以下例子2
//1.cpp
extern const int i; //const int i = 1;
const int i = 1; //extern const int i;
int main(){return 0;}
//2.cpp
extern const int i = 2;
只有按1.cpp中注释的写法能通过链接
按照编译的顺序检查文件,先 extern const int i,这时编译器会找这句之前是否对 i 进行了初始化,如果没有,则通过 extern 去文件外部,在 2.cpp 寻找到了对 i 的定义。这时,i 已经完成了定义。回到1.cpp后,发现了 const int i = 1,这时就会报错,重复定义:one or more multiply defined symbols found。按注释顺序,当extern const int i 时,已经在这个文件发现了对 i 的定义,不需要外部链接。
这里关于编译的知识还需要补一下