为什么在头文件中声明的全局变量会导致链接器出错

3
我已经在header.h中声明了一个全局变量,并将该头文件包含在source.cpp和main.cpp中,但链接器报错。
Source.obj : error LNK2005: "int globalVariable" (?globalVariable@@3HA) already defined in     Main.obj
GlobalVariableAndLinkageIssue.exe fatal error LNK1169: one or more multiply defined symbols found

header.h

int globalVariable;

source.cpp

#include "header.h"

main.cpp

#include"header.h"

void main() {}

可能是https://dev59.com/d3M_5IYBdhLWcg3wThR3的重复问题。 - WhozCraig
5个回答

3
  1. 将声明移至 .cpp 文件中。您可以使用以下方法在头文件中使用声明:

    extern int globalVariable; // 在头文件中进行声明,可以有多个

    但是,在 .cpp 文件中应该进行定义:

    int globalVariable; // 在 .cpp 文件中进行定义,整个工程只需要一个就可以了

    C 和 C++ 使用文本预处理器来包含头文件,这基本上是一种文本插入,而不是像某些语言中的智能模块系统。通过像您一样包含它,您正在创建多个定义,每个 .cpp 文件一个。

  2. 作为良好实践的一部分,您需要习惯使用 include guards 来防止多个嵌套包含(虽然它无法解决您当前的问题)。如果使用 Visual C++,可以使用 #pragma once 或者使用可移植的解决方案将您的头文件代码包装在:

    #ifndef _INCLUDE_FOO_H_

    #endif


1
要创建全局变量,您需要按照以下步骤操作。请注意,在头文件中,我们将变量标记为extern,实际上是在cpp文件中创建对象。

header.h

extern int globalVariable;

header.cpp

#include "header.h"
int globalVariable;

main.cpp

#include "header.h"

int main() {}

1
将全局变量放在某个 .c 或 .cpp 文件中,这样它只能被定义一次,并且可以使用 extern 在头文件中进行引用。例如:

header.h

extern int globalVariable;

header.cpp

int globalVariable = 0;

source.cpp

#include "header.h"

main.cpp

#include"header.h"

int main() {
  return 0;
}

0

由于两个源文件都包含了您的头文件,因此它被定义了两次。


-2
在这种情况下,通常会使用以下一些 #define:
//header.h
#ifdef DEFINE_VARS
   #define DEFINE_OR_DECLARE 
#else
   #define DEFINE_OR_DECLARE extern
#endif

DEFINE_OR_DECLARE int globalVariable;


//main.cpp
#define DEFINE_VARS
#include "header.h"
...

//header.cpp
#include "header.h"
...

我绝不会推荐这个。 - Bill Lynch
请问您能否详细解释一下为什么? - Ron Pinkas
假设我想让 globalVariable 的默认值为 4。那么我可以这样写:DEFINE_OR_DECLARE int globalVariable = 4;。这会导致警告信息,看起来像这样:a.c:1: warning: ‘x’ initialized and declared ‘extern’ - Bill Lynch
但是您绝不会在这种情况下指定一个赋值。这种技术非常有生产力,可以确保头文件永远不会错过新引入的var[s]。然后,在定义源中使用初始化例程,以避免您所描述的默认值情况。 - Ron Pinkas

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接