循环 #include 的标头防护问题[重复]

问题描述 投票:0回答:6

我正在制作一个小型C++框架,其中包含许多.h和.cpp。

我创建了一个通用包含,其中包含我所有的 .h 文件,例如:

framework.h

#include "A.h"
#include "B.h"
#include "C.h"

每个 .h 标头都受到包含保护的保护,例如

#ifndef A_HEADER
#define A_HEADER
...
#endif

问题是,我希望能够在所有子 .h 中包含“framework.h”,例如,但它会导致很多编译器错误:

#ifndef A_HEADER
#define A_HEADER

#include "framework.h"
...
#endif

如果我为每个子标头使用真正的头文件,并为使用我的框架的框架使用framework.h,那么它工作得很好..

我只想将主标头包含在我的所有子 .h 中,这样我就不需要每次都包含所有依赖项。

谢谢:)

c++ header include circular-dependency include-guards
6个回答
7
投票

基本上你所做的是framework.h中的

#include "A.h"
和A.h中的
#include "framework.h"
。这会导致头文件的循环依赖,并且您将收到诸如未定义的类 A 之类的错误。要解决此问题,请在头文件中使用前向声明,并仅在相应的 cpp 文件中使用
#include
。如果这是不可能的,那么除了包含单独的头文件之外,我看不到任何其他选项。


2
投票

不应将主头文件包含在子头文件中。它应该用来让用户的生活更轻松,而不是你的。

而是执行以下操作:

1)在相关子头文件中对所有需要的内容进行前向定义。

2) 仅在 CPP 文件中包含所需的子头文件。

3)当在应用程序代码中使用框架时(例如),您可以包含主框架头文件。


1
投票

只需用包含防护来保护主标头即可:

#ifndef FRAMEWORK_H
#   define FRAMEWORK_H
#   include <A.h>
#   include <B.h>
#   include <C.h>
#endif

这将防止递归包含。


0
投票

我建议使用 #pragma Once,并将其放置在所有头文件(framework.h、A.h、B.h 和 C.h)的顶部。

尽管如此,如果您愿意,我认为您也可以通过简单地在 Framework.h 中添加包含保护来解决您的问题。


0
投票

我猜你在B和C之间有依赖关系,这样B依赖于C,但在framework.h中C包含在B之后。


0
投票

在 C++ 中,循环包含通常是一个坏主意。虽然使用标头保护可以防止预处理器进入无限循环(或因此引发错误),但您会遇到意外的编译器错误,因为在某些时候,如果您认为是,则不会包含头文件。

您应该包含

A.h
中的
B.h
C.h
framework.h
,并且在
A.h
中,不要包含
framework.h
,只需向前声明您从中使用的类即可。或者反过来做:包含来自
framework.h
A.h
B.h
C.h
,并在
framework.h
中转发声明类。当然,将需要比
class A
更详细声明的所有代码放入 .cpp 文件中。

© www.soinside.com 2019 - 2024. All rights reserved.