我有一种情况,需要在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
为了解决这个问题,答案建议在这里出现类似的情况;我的include保护程序防止递归包含和多个符号定义吗?我们使用吗
inline or static
其中内联是首选
- 为什么内联优先于静态
- 内联只能与函数一起使用
由于我只在变量上得到错误,所以当我将堆栈s重新定义为:时,错误就会消失
static std::stack<int> s;
static int a;
对这里可能发生的事情有什么想法吗?如果有帮助的话,我将使用Xcode 6。非常感谢您的帮助!
提前谢谢。
由于stack.cpp执行以下操作,因此存在多个定义错误:
stack<int> s;
main.cpp还定义了一个堆栈:
stack<int> s;
您有两个定义了相同名称的不同全局对象,这会导致未定义的行为(幸运的是,您的链接器对其进行了诊断)。
相反,您可能想要做的是拥有一个由几个不同单元引用的单个堆栈。为了实现这一点,您只能让定义堆栈的行出现一次。(请记住,#include
只是一个直接的文本替换;您的代码的行为与将stack.h
的内容复制粘贴到每个.cpp
文件的主体中的行为相同)。
其他单元需要有一行字,上面写着"在某个地方(但不是这里)定义了一个名为s
的stack<int>
",其代码为:
extern stack<int> s;
因此,您应该将这一行放在头文件中,并将stack<int> s;
正好放在一个.cpp文件中——不管是哪一个。
在函数的情况下,您不在标头中定义任何函数,只声明。如果您在标头中定义了一个函数(例如void print() { }
),则会出现相同的多重定义错误,从而导致未定义的行为。