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

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.hb.h,并再次b.h包括util.h,所以我得到了多个def错误.但它似乎没有意义,因为在util.h我写#ifndef/#define卫兵.

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

Gor*_*ley 6

你的问题是由定义而不是简单地 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)

或者,或者,声明foostaticinline:

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)

只有当您想要内联函数时,才需要执行此操作.在这种情况下,编译器需要在使用它的每个转换单元中定义函数,因为它基本上变成了编译时宏.