头文件中的静态变量

时间:2011-02-18 11:06:00

标签: c++ one-definition-rule

静态变量具有文件范围。假设我有以下两个文件:

  • file1.h
  • file1.cpp
  • file2.h
  • file2.cpp

我在两个头文件中都声明了静态变量static int Var1file1.hfile2.h都包含在main.cpp文件中。

我这样做是因为静态变量将具有文件范围,因此它不会相互冲突。 但在编译后我发现它显示出冲突。

现在,静态变量的行为类似于extern变量。另一方面,如果我在两个.cpp文件中声明静态变量,它编译得很好。

我无法理解这种行为。

任何机构都可以解释范围和链接在这种情况下的工作方式。

3 个答案:

答案 0 :(得分:16)

静态变量是编译单元的本地变量。编译单元基本上是.cpp文件,其中插入.h文件的内容代替每个#include指令。

现在,在编译单元中,您不能拥有两个具有相同名称的全局变量。这就是您的情况:main.cpp包括file1.hfile.h,两个标头中的每一个都定义了自己的Var1

如果逻辑上这些是两个不同的变量,请给它们不同的名称(或将它们放在不同的名称空间中)。

如果这些变量是同一个变量,请将其移至单独的标题文件var1.h中,并包括var1.hfile1.h中的file2.h,而不要忘记var1.h 3}}在{{1}}。

答案 1 :(得分:9)

静态变量具有翻译单元范围(通常是.c.cpp文件),但#include指令只是逐字复制文件的文本,而不创建另一个翻译单元。预处理后,这个:

#include "file1.h"
#include "file2.h"

将变成这个:

/* file1.h contents */
static int Var1;

/* file2.h contents */
static int Var1;

如您所知,这是无效的。

答案 2 :(得分:2)

假设静态变量static int Var1在两个标头中都处于全局范围,并且包含main.cpp中的标头。现在,首先预处理器将包含文件的内容复制到main.cpp。因为,在main.cpp处,Var1在同一范围内声明了两次,所以会出现多个声明错误。 (即,预处理器从file1.h复制的另一种形式file2.h

每个源文件都是单独编译的。现在,当您在源文件中单独声明时,每个源文件都不知道另一个存在于具有相同名称的源文件中的其他静态变量。因此,编译器不会报告错误。如果要在源文件之间共享变量,可以将其标记为extern。