C++ 包含守卫和多重定义错误

C++ include guards and multiple definition errors

我有一种情况需要在 2 个 .cpp 文件中包含一个头文件 (stack.h)。

设置如下:

//------"stack.h"------//
std::stack<int> s;
int a;
void doStackOps();
void print();

//------"stack.cpp"------//
#include "stack.h"


//------"main.cpp"------//
#include "stack.h"

问题 1

我的头文件包含2个变量和2个方法。我似乎只收到变量的多个定义错误,为什么会这样?难道不应该抱怨函数的重新定义吗?

错误看起来像:

duplicate symbol _stacks in:
/Users/.....stack.o
/Users/......main.o
ld: 1 duplicate symbol for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

问题 2

为了解决这个问题,这里针对类似情况建议的答案 Why aren't my include guards preventing recursive inclusion and multiple symbol definitions? 是我们使用

inline or static 

首选内联

因为我只得到变量的错误,所以当我将堆栈 s 重新定义为时,错误消失了:

static std::stack<int> s; 
static int a; 

对这里可能发生的事情有什么想法吗?如果有帮助,我正在使用 Xcode 6。非常感谢任何帮助!

提前致谢。

存在多个定义错误,因为 stack.cpp 确实:

stack<int> s;

和main.cpp也定义了一个栈:

stack<int> s;

你有两个不同的全局 objects 定义了相同的名称,这会导致未定义的行为(幸运的是你的链接器诊断它)。

相反,您可能打算做的是拥有一个由多个不同单元引用的堆栈。为此,您只能让定义堆栈的行出现一次。 (请记住 #include 只是一个直接的文本替换;您的代码的行为与将 stack.h 的内容 copy-pasted 放入每个 .cpp 的 body 相同文件)。

其他单位需要有一行写着 "There is a stack<int> called s defined somewhere (but not here)" 的代码是:

extern stack<int> s;

所以你应该把那行放在你的 header 文件中,然后把 stack<int> s; 放在一个 .cpp 文件中 - 哪个都不重要。


在函数的情况下,您不在header中定义任何函数,只声明。如果您在 header 中定义了一个函数(例如 void print() { }),那么您将遇到相同的多重定义错误,导致未定义的行为。