Primer Plus 内存模型和名称空间
单独编译
链接编译模块时,需确保所有对象文件或库都是由同一个编译器生成的
因为不同编译器可能用不同方式实现名称修饰
1 | // Rectangle.h |
1 | // Rectangle.cpp |
1 |
|
执行 g++ Lab.cpp Rectangle.cpp 后会发生如下:
预处理器将包含的文件与源代码文件合并,产生临时文件temp1.cpp和temp2.cpp
编译器生成每个源代码文件的目标代码文件Lab.o和Rectangle.o
链接程序将目标代码文件、库代码和启动代码合并,生成可执行文件a.out
存储持续性、作用域和链接性
自动存储持续性:函数定义中声明的变量,出了定义域就自动释放
静态存储持续性:函数定义外定义的变量和static修饰的变量,在程序整个运行过程中都存在
线程存储持续性(C++11):thread_local修饰的变量,生命周期和所属线程一样长
动态存储持续性:用new分配的内存将一直存在,直到用delete释放或程序结束
自动变量没有链接性
静态变量有外部链接性(可在其他文件中访问),内部链接性(只能在当前文件中访问)和无链接性(只能在当前函数或代码块中访问)
注意static用于局部声明时,表示存储持续性,用于代码块外的声明时,表示内部链接性
1 | int global = 1000; // 静态存储,外部链接 |
extern 关键字
引用声明其他文件的外部变量,不分配存储空间,且不进行初始化
1 | // Lab.cpp |
1 | // Lab2.cpp |
在变量前面加上::可以显式地使用该变量的全局版本
1 |
|
两个文件中有一个同名的外部变量,将无法通过编译
需将其中一个加上static,静态变量将隐藏外部变量
说明符和限定符
volatile关键字表明变量的内存单元即使没有被代码修改,其值也可能改变(由于硬件),告诉编译器不要进行神秘的优化
mutable关键字指出即使结构或变量为const,其某个成员也可被修改(珂朵莉树有用到来着)
const全局变量的链接性为内部的(就是说const全局定义蕴含了static),想要其链接性为外部必须显式地用extern关键字,其他文件也必须用extern来引用声明
函数和链接性
函数都默认是静态持续,外部链接性的,也可用static显示定义为内部链接的
namespace
namespace可以是全局的,也可以在另一个namespace里,但不能在代码块里
在namespace里声明的名称的链接性默认为外部的
namespace是开放的,可以一段一段写
指导原则
用namespace里声明的变量,而不是外部全局变量和静态全局变量
1 | // config.h |
1 | // config.cpp |
1 |
|