我遇到需要在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"
我的头文件包含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)
为了解决这个问题,答案提出了类似的情况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.非常感谢任何帮助!
提前致谢。
答案 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() { }
),那么您将获得相同的多重定义错误,从而导致未定义的行为。