【问题标题】:Static variable in a Header File头文件中的静态变量
【发布时间】:2011-06-29 18:11:25
【问题描述】:
静态变量具有文件范围。假设我有以下两个文件:
- file1.h
- file1.cpp
- file2.h
- file2.cpp
我在两个头文件中都声明了静态变量static int Var1。 file1.h 和 file2.h 都包含在 main.cpp 文件中。
我这样做是因为静态变量将具有文件范围,因此不会相互冲突。
但是编译后发现有冲突。
现在静态变量的行为类似于extern 变量。另一方面,如果我在两个 .cpp 文件中声明静态变量,它编译得很好。
我无法理解这种行为。
任何机构都可以解释范围和链接在这种情况下是如何工作的吗?
【问题讨论】:
标签:
c++
one-definition-rule
【解决方案1】:
静态变量是编译单元的本地变量。一个编译单元基本上是一个.cpp 文件,其中插入了.h 文件的内容来代替每个#include 指令。
现在,在编译单元中不能有两个同名的全局变量。这就是您的情况:main.cpp 包括file1.h 和file.h,并且两个标头中的每一个都定义了自己的Var1。
如果在逻辑上它们是两个不同的变量,请给它们不同的名称(或将它们放在不同的命名空间中)。
如果它们是同一个变量,请将其移至单独的头文件 var1.h,并包含来自 file1.h 和 file2.h 的 var1.h,不要忘记 var1.h 中的 #include guard。
【解决方案2】:
静态变量具有翻译单元范围(通常是.c 或.cpp 文件),但#include 指令只是逐字复制文件的文本,不会创建另一个翻译单元。预处理后,如下:
#include "file1.h"
#include "file2.h"
会变成这样:
/* file1.h contents */
static int Var1;
/* file2.h contents */
static int Var1;
如您所知,这是无效的。
【解决方案3】:
假设静态变量 static int Var1 在两个标头中都处于全局范围内,并且两个标头都包含在 main.cpp 中。现在,首先预处理器将包含文件的内容复制到main.cpp。由于在main.cpp 有Var1 在同一范围内声明了两次,因此会出现多次声明错误。 (即,预处理器从file1.h 复制一个,另一个从file2.h 复制)
每个源文件都是单独编译的。现在,当您在它们的源文件中单独声明时,每个源文件都不知道存在于另一个具有相同名称的源文件中的另一个静态变量。因此,编译器不会报告错误。如果您希望在源文件之间共享变量,可以将其标记为 extern。