如果您必须有全局变量,通常的做法是在 .h 文件中声明它们并在一个(并且只有一个).cpp 文件中定义它们。
在 .h 文件中;
extern int x;
在 .cpp 文件中;
int x=3;
我使用了 int (也许是最基本的基本类型?)而不是 const char * ,因为您的问题的本质不取决于变量的类型。
基本思想是您可以多次声明一个变量,因此每个包含 .h 文件的 .cpp 文件都声明该变量,这很好。但是你只定义一次。定义是您为变量分配初始值的语句(使用 =)。您不希望在 .h 文件中定义,因为如果 .h 文件包含在多个 .cpp 文件中,您将获得多个定义。如果您对一个变量有多个定义,那么在链接时就会出现问题,因为链接器想要分配变量的地址,并且如果它有多个副本,则无法合理地做到这一点。
稍后添加的附加信息试图缓解 Sud 的困惑;
尝试将您的问题减少到最小的部分以更好地理解它;
假设您有一个包含三个 .cpp 文件的程序。为了构建程序,每个 .cpp 都被单独编译以创建三个目标文件,然后将三个目标文件链接在一起。如果三个.cpp文件如下(示例A,组织好);
文件1.cpp
extern int x;
文件2.cpp
extern int x;
文件 3.cpp
extern int x;
然后文件将毫无问题地编译并链接在一起(至少就变量 x 而言)。没有问题,因为每个文件只声明变量 x。声明只是说明在某处我可能(或可能不会)使用的变量。
以下是实现相同目标的更好方法(示例 A,更好的组织);
头文件.h
extern int x;
文件1.cpp
#include "header.h"
文件2.cpp
#include "header.h"
文件 3.cpp
#include "header.h"
这实际上是完全相同的,对于三个编译中的每一个,编译器在处理 .cpp 文件(或专家称之为翻译单元)时看到的文本都相同,因为 #include 指令只是从另一个文件中提取文本. 尽管如此,这是对前面示例的改进,因为我们只将声明放在一个文件中,而不是在多个文件中。
现在考虑另一个工作示例(示例 B,良好的组织);
文件1.cpp
extern int x;
文件2.cpp
extern int x;
文件 3.cpp
extern int x;
int x=3;
这也可以正常工作。所有三个 .cpp 文件都声明了 x 并且一个实际定义了它。我们可以继续在操作变量 x 的三个文件中的任何一个中的函数中添加更多代码,我们不会得到任何错误。同样,我们应该使用一个头文件,以便声明只进入一个物理文件(示例 B,更好的组织)。
头文件.h
extern int x;
文件1.cpp
#include "header.h"
文件2.cpp
#include "header.h"
文件 3.cpp
#include "header.h"
int x=3;
最后考虑一个不起作用的例子(例子C,不起作用);
文件1.cpp
int x=3;
文件2.cpp
int x=3;
文件 3.cpp
int x=3;
每个文件都可以毫无问题地编译。问题发生在链接时,因为现在我们已经定义了三个单独的 int x 变量。它们具有相同的名称并且都是全局可见的。链接器的工作是将单个程序所需的所有对象提取到一个可执行文件中。全局可见的对象必须具有唯一的名称,以便链接器可以将对象的单个副本放在可执行文件中一个定义的地址(位置),并允许所有其他对象在该地址访问它。在这种情况下,链接器无法使用全局变量 x 完成它的工作,因此会扼杀一个错误。
顺便说一句,给出不同的定义不同的初始值并不能解决问题。在每个定义之前加上关键字 static 确实解决了这个问题,因为现在变量不是全局可见的,而是在定义的 .cpp 文件中可见。
如果将全局变量定义放入头文件中,则基本没有任何变化(例如 C,头文件组织在这种情况下没有帮助);
头文件.h
int x=3; // Don't put this in a .h file, causes multiple definition link error
文件1.cpp
#include "header.h"
文件2.cpp
#include "header.h"
文件 3.cpp
#include "header.h"
唷,我希望有人读到这篇文章并从中受益。有时提问者急需一个简单的基本概念解释,而不是高级计算机科学家的解释。