头文件包含循环和多重定义

时间:2012-08-09 03:37:28

标签: c++ include-guards multiple-definition-error

我有util.h包含将在a.h和'b.h'中使用的函数,而且a.hb.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.hb.h,而b.h再次包含util.h,所以我得到了多个def错误。但它似乎没有意义,因为在util.h我写了#ifndef/#define警卫。

任何人都可以给我一个帮助,谢谢。

1 个答案:

答案 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声明为staticinline

<强> 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你的功能时,才需要这样做。在这种情况下,编译器需要在每个使用它的翻译单元中定义函数,因为它基本上变成了编译时宏。