0

我有一个util.h包含一个函数,它将用于a.h和'bh',以及更多,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 definitionfoo. 如何?

我认为问题可能是,a.h包括util.hb.h,并再次b.h包括,所以我得到了多个 def 错误。util.h但这似乎没有意义,因为util.h我写了#ifndef/#define守卫。

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

4

1 回答 1

6

您的问题是由定义而不是简单地在内部声明引起的 fooutils.h

对于这个例子,假设我们有:

a.cpp

#include "a.h"

b.cpp

#include "b.h"

主文件

#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";
}

主文件

void foo()
{
    std::cout << "foo\n";
}

int main(){
    foo();
    return 0;
}

现在,当您编译时,您有 3 个定义foo(它们都是相同的,但这无关紧要)。编译后,链接器无法知道为任何给定的调用选择哪个定义,foo因此会产生错误。

而不是foo在标题中定义,而是在其中定义它utils.cpp并且只在其中放置一个声明utils.h,例如

实用程序.h

#ifndef _UTIL_H_
#define _UTIL_H_

void foo();

#endif

或者,或者,声明foostaticor inline

实用程序.h

#ifndef _UTIL_H_
#define _UTIL_H_

static void foo()
{
    std::cout << "foo\n";
}

/* OR */

inline void foo()
{
    std::cout << "foo\n";
}


#endif

只有当您想内联您的函数时,您才需要这样做。在这种情况下,编译器需要在每个使用它的翻译单元中定义函数,因为它本质上变成了编译时宏。

于 2012-08-09T04:02:20.057 回答