C ++包括警卫和多重定义错误

时间:2015-02-23 03:09:51

标签: c++ header-files redefinition include-guards

我遇到需要在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 

其中内联是首选

  • 为什么内联比静态优先?
  • 内联只能用于函数吗?

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

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

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

提前致谢。

1 个答案:

答案 0 :(得分:0)

有多个定义错误,因为stack.cpp会:

stack<int> s;

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

stack<int> s;

您使用相同的名称定义了两个不同的全局对象,这会导致未定义的行为(幸运的是,您的链接器会对其进行诊断)。

相反,你可能想做的是拥有一个由几个不同单位引用的单个堆栈。要实现这一点,您只能使用定义堆栈的行出现一次。 (请记住,#include只是一个直接的文本替换;您的代码行为与将stack.h的内容复制粘贴到每个.cpp文件的正文中的行为相同。

其他单位需要有一行代表“有一个名为stack<int> s已在某处定义(但不在此处)”,其代码为:

extern stack<int> s;

因此,您应该将该行放在头文件中,并将stack<int> s;放在一个.cpp文件中 - 无关紧要。


对于函数,您不在头文件中定义任何函数,只声明。如果您在标题中定义了一个函数(例如void print() { }),那么您将获得相同的多重定义错误,从而导致未定义的行为。