2011-02-18 80 views
7

静态变量具有文件范围。说我有两个以下文件:
头文件中的静态变量

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

我已经声明为static变量都表示static int Var1头文件。 main.cpp文件中包含file1.hfile2.h

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

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

我无法理解此行为。

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

+0

相关的,请参见[不要在头文件中定义一个未命名的名称空间](https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+未命名+名称空间+中的+ a +标题+文件) – jww 2018-02-20 16:47:14

回答

13

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

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

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

如果这些是相同的变量,将其移动到一个单独的头文件,var1.h,并且包括var1.h来自file1.hfile2.h,不要忘记在var1.h#include guard

2

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

每个源文件被单独编译。现在,当你在它们的源文件中分别声明时,每个源文件都不知道另一个具有相同名称的源文件中存在的另一个静态变量。所以,编译器不会报告错误。如果您希望在源文件之间共享变量,您可以将其标记为extern。

8

静态变量的翻译单元范围(通常为.c.cpp文件),但文件的#include指令只是拷贝文本逐字,并且不会创建另一个翻译单位。预处理之后,这样的:

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

会变成这样:

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

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

其中,如你所知,是无效的。

+0

我的瘦身是会有两个编译单元的。感谢您通过疑惑清除 – 2011-02-22 11:29:30