第九章
下文仅为自己的阅读理解顺序,标号和书本的并不完全一致。
9.1 单独编译
同一个文件只能将同一个头文件包含一次,如果同一个头文件被多次包含,那么在编译过程中,每次包含都会将该头文件中的所有声明和定义视为新的。在某些情况下,这会导致重定义错误(例如两次定义同一个函数或类)
头文件通常使用条件编译指令#ifndef、#define和#endif来实现包含保护。
// MyHeader.h
#ifndef MY_HEADER_H // 检查是否已定义
#define MY_HEADER_H // 如果没有,则定义它
// 头文件内容
class MyClass {
public:
void myFunction();
};
#endif // 结束条件编译
如果#ifndef检查已经定义了,则直接跳到#endif这行。
- 尖括号(< >)和双引号(" ")的头文件格式
两种方式之间的主要区别在于它们搜索头文件的位置和优先级。<>尖括号优先用于包含系统库或标准库的头文件;双引号 (" ") 首先搜索当前源文件所在目录,然后搜索标准库目录。
9.2 存储持续性、作用域、链接性
9.2.1 作用域持续性
- 自动存储持续性: 函数为例子,创建或执行函数时候存储被创建,结束时内存被释放。
- 静态存储持续性: static的全局变量。
- 线程存储持续性: thread_local来声明的变量,生命周期和所在线程一样长。
- 动态存储持续性:如new和delete运算符的使用
9.2.2 静态持续变量
静态变量可以有三种连接性:内部连接性(internal linkage)、外部连接性(external linkage) 和 无连接性(no linkage)
1、 内部连接性
// file1.cpp
static int internalVar = 10; // 内部连接性
void func() {
internalVar++;
}
// file2.cpp
#include <iostream>
extern int internalVar; // 不能访问,internalVar在file1.cpp中不可见
int main() {
// std::cout << internalVar; // 错误:internalVar 不可见
return 0;
}
2、 外部连接性
// file1.cpp
int externalVar = 20; // 外部连接性
void func() {
externalVar++;
}
// file2.cpp
#include <iostream>
extern int externalVar; // 声明,指向同一个变量
int main() {
std::cout << externalVar; // 正确:访问shared externalVar
return 0;
}
3、 无连接性
localVar 是一个局部静态变量
#include <iostream>
void func() {
static int localVar = 30; // 无连接性
localVar++;
std::cout << localVar << std::endl; // 输出 localVar 的值
}
int main() {
func(); // 输出 30
func(); // 输出 31
return 0;
}
那为什么不直接用普通变量int localVar呢?
作用域: 普通局部变量的作用域仅限于其定义的函数内。(相同)
普通变量生命周期: 每次调用函数时,都会创建一个新的实例(即该变量会在每次进入函数时被重新初始化),函数返回后,该实例便失效,内存释放。因此,其值在多次调用之间不会被保留。
static变量生命周期: 静态局部变量在程序的整个运行期间都存在,仅在第一次调用该函数时初始化。之后,它的值在多个函数调用之间保持不变,直到程序结束时才会被销毁。
9.2.3 说明符和限定符
1、auto:
表示局部变量的存储在栈上,生命周期限于所在的代码块。在 C++11 前,auto为自动变量,所有局部变量都是“自动变量”,因此使用 auto 是多余的;而C++11之后,auto用于自动类型判断。
2、register:
提示编译器将变量尽量存储在 CPU 寄存器中以提高访问速度。不保证变量一定存储在寄存器中,取决于编译器。register 变量不能直接取地址(不能用 & 操作符)
3、static:
控制变量或函数的作用域和生命周期。
- static 用在局部变量:同上文的 无连接性
- static 用在全局变量:moduleVar 是全局变量,但因为加了 static,只能在 File1.cpp 中使用,File2.cpp 无法访问。
// File1.cpp :这是第一个文件
#include <iostream>
static int moduleVar = 42; // 静态全局变量,仅在本文件可见
void showModuleVar() {
std::cout << "moduleVar: " << moduleVar << "\n";
}
// File2.cpp :这是第二个文件
#include <iostream>
extern int moduleVar; // 错误:无法访问其他文件的 static 变量
void dummyFunction() {
std::cout << moduleVar; // 无法访问
}
- static 用在函数:
// File1.cpp :这是第一个文件
#include <iostream>
static void