头文件中包含静态全局变量有意义吗?

问题描述 投票:0回答:3

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

  • 文件1.h
  • 文件1.cpp
  • 文件2.h
  • 文件2.cpp

我在两个头文件中都声明了静态变量

static int Var1
file1.h
file2.h
都包含在
main.cpp
文件中。

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

现在静态变量的行为就像一个

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

我无法理解这种行为。

任何人都可以解释一下范围和链接在这种情况下是如何工作的吗?

c++ global-variables header-files linkage one-definition-rule
3个回答
28
投票

静态变量是编译单元的本地变量。 编译单元基本上是一个

.cpp
文件,其中插入了
.h
文件的内容来代替每个
#include
指令。

现在,在一个编译单元中不能有两个同名的全局变量。这就是您的情况所发生的情况:

main.cpp
包括
file1.h
file.h
,两个标头中的每一个都定义了自己的
Var1

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

如果这些是相同的变量,请将其移至单独的头文件

var1.h
中,并包含
var1.h
file1.h
中的
file2.h
,不要忘记 var1.h 中的
#include Guard


17
投票

静态变量具有翻译单元范围(通常是

.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。

© www.soinside.com 2019 - 2024. All rights reserved.