第九章 内存模型和名称空间 C++ Primer Plus(附带例子)

第九章

下文仅为自己的阅读理解顺序,标号和书本的并不完全一致。

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 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是zp

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值