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

header file include-loop and multiple definition

本文关键字:定义 循环 文件包      更新时间:2023-10-16

我有一个包含函数的util.h,该函数将在a.h和'b.h'中使用,此外,a.hb.h将相互包含,以便访问彼此定义的一些类。

//util.h
#ifndef _UTIL_H_
#define _UTIL_H_
#include <iostream>
void foo()
{
    std::cout << "foon";
}
#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

我的问题是,我foo multiple definition错误.如何?

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

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

您的问题是由定义而不是简单地utils.h中声明foo引起的

对于此示例,假设我们有:

答.cpp

#include "a.h"

乙.cpp

#include "b.h"

主.cpp

#include "a.h"
#include "b.h"
#include "utils.h"

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

经过预处理,但在编译之前,您的文件现在看起来像这样(这是一种简化,但您明白了):

答.cpp

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

乙.cpp

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

主.cpp

void foo()
{
    std::cout << "foon";
}
int main(){
    foo();
    return 0;
}

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

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

实用性.h

#ifndef _UTIL_H_
#define _UTIL_H_
void foo();
#endif

或者,将foo声明为 staticinline

实用性.h

#ifndef _UTIL_H_
#define _UTIL_H_
static void foo()
{
    std::cout << "foon";
}
/* OR */
inline void foo()
{
    std::cout << "foon";
}

#endif

仅当您要内联函数时,才需要执行此操作。在这种情况下,编译器需要在使用它的每个翻译单元中定义函数,因为它本质上变成了一个编译时宏。