C++包含保护和多个定义错误

C++ include guards and multiple definition errors

本文关键字:定义 错误 包含 保护 C++      更新时间:2023-10-16

我有一种情况,需要在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文件的主体中的行为相同)。

其他单元需要有一行字,上面写着"在某个地方(但不是这里)定义了一个名为sstack<int>",其代码为:

extern stack<int> s;

因此,您应该将这一行放在头文件中,并将stack<int> s;正好放在一个.cpp文件中——不管是哪一个。


在函数的情况下,您不在标头中定义任何函数,只声明。如果您在标头中定义了一个函数(例如void print() { }),则会出现相同的多重定义错误,从而导致未定义的行为。