Alc*_*ott 0 c++ include-guards multiple-definition-error
我有一个util.h包含一个函数,它将用于a.h和'b.h',以及更多,a.h并将b.h相互包含,以便访问彼此定义的一些类.
//util.h
#ifndef _UTIL_H_
#define _UTIL_H_
#include <iostream>
void foo()
{
std::cout << "foo\n";
}
#endif
//a.h, it has a a.cpp
#ifndef _A_H_
#define _A_H_
#include "util.h"
#include "b.h"
//some classes' definition
#endif
//b.h, it has a b.cpp
#ifndef _B_H_
#define _B_H_
#include "util.h"
#include "a.h"
//some classes' definition
#endif
Run Code Online (Sandbox Code Playgroud)
我的问题是,我得到了multiple definition错误foo.怎么样?
我认为问题可能是,a.h包括util.h和b.h,并再次b.h包括util.h,所以我得到了多个def错误.但它似乎没有意义,因为在util.h我写#ifndef/#define卫兵.
任何人都可以给我一个帮助,谢谢.
你的问题是由定义而不是简单地在 foo内部声明引起的utils.h
对于这个例子,假设我们有:
a.cpp
#include "a.h"
Run Code Online (Sandbox Code Playgroud)
b.cpp
#include "b.h"
Run Code Online (Sandbox Code Playgroud)
main.cpp中
#include "a.h"
#include "b.h"
#include "utils.h"
int main(){
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在预处理之后,但在编译之前,您的文件现在看起来像这样(这是一个简化,但您明白了):
a.cpp
void foo()
{
std::cout << "foo\n";
}
Run Code Online (Sandbox Code Playgroud)
b.cpp
void foo()
{
std::cout << "foo\n";
}
Run Code Online (Sandbox Code Playgroud)
main.cpp中
void foo()
{
std::cout << "foo\n";
}
int main(){
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
现在编译时,你有3个定义foo(它们都是相同的,但这是无关紧要的).编译之后,链接器无法知道为任何给定的调用选择哪个定义foo,因此它会生成错误.
而不是foo在标题中定义,而是定义它,utils.cpp并且仅在utils.h例如中放入声明
utils.h
#ifndef _UTIL_H_
#define _UTIL_H_
void foo();
#endif
Run Code Online (Sandbox Code Playgroud)
或者,或者,声明foo为static或inline:
utils.h
#ifndef _UTIL_H_
#define _UTIL_H_
static void foo()
{
std::cout << "foo\n";
}
/* OR */
inline void foo()
{
std::cout << "foo\n";
}
#endif
Run Code Online (Sandbox Code Playgroud)
只有当您想要内联函数时,才需要执行此操作.在这种情况下,编译器需要在使用它的每个转换单元中定义函数,因为它基本上变成了编译时宏.