我有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
我的问题是,multiple definition
出现foo
错误。怎么样?
我认为问题可能是a.h
包括util.h
和b.h
,而b.h
再次包含util.h
,所以我得到了多个def错误。但它似乎没有意义,因为在util.h
我写了#ifndef/#define
警卫。
任何人都可以给我一个帮助,谢谢。
答案 0 :(得分:6)
您的问题是由定义而不是简单地在foo
中声明 utils.h
引起的
对于这个例子,假设我们有:
<强> a.cpp 强>
#include "a.h"
<强> b.cpp 强>
#include "b.h"
<强>的main.cpp 强>
#include "a.h"
#include "b.h"
#include "utils.h"
int main(){
foo();
return 0;
}
在预处理之后,但在编译之前,你的文件现在看起来像这样(这是一个简化,但你明白了):
<强> a.cpp 强>
void foo()
{
std::cout << "foo\n";
}
<强> b.cpp 强>
void foo()
{
std::cout << "foo\n";
}
<强>的main.cpp 强>
void foo()
{
std::cout << "foo\n";
}
int main(){
foo();
return 0;
}
现在编译时,你有foo
的3个定义(它们都是相同的,但这是无关紧要的)。编译之后,链接器无法知道对foo
的任何给定调用选择哪个定义,因此会生成错误。
不是在标题中定义foo
,而是在utils.cpp
中定义,只在utils.h
中添加声明,例如
<强> utils.h 强>
#ifndef _UTIL_H_
#define _UTIL_H_
void foo();
#endif
或者,将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
只有当你想要inline你的功能时,才需要这样做。在这种情况下,编译器需要在每个使用它的翻译单元中定义函数,因为它基本上变成了编译时宏。