C++ 中的相互包含..它是如何工作的? [重复]

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

可能重复:
解决由于类之间的循环依赖而导致的构建错误

我对 C++ 很陌生,标题中提出了这个问题。或者更准确地说:如果 A.h 包含 B.h 并且 B.h 包含 A.h,我会收到一条错误消息,因为“include# file "C:...\A.h" 包含其自身”。文件:B.h

我找不到解决这个问题的方法,而且我的一般设置几乎需要这些类之间的关系。 有可能让这项工作成功吗?

c++ include header-files
7个回答
7
投票

简单:不要让 A.h 包含 B.h。反之亦然。

一般来说,头文件应该包含尽可能少的内容。您可以使用前向声明来绕过许多包含。唯一必须在标头中包含某些内容的情况是,该标头中存在用作非引用的对象。

所以要避免这样做。使用 Pimpl 避免将类成员放入标头中。除非它是模板代码或者您需要内联支持,否则不要在标题中编写实际代码。

最坏的情况是您需要创建一个 C.h 来定义 A.h 和 B.h 的需求。


7
投票

在头文件中使用“包含防护”。 http://en.wikipedia.org/wiki/Include_guard

#ifndef MYHEADER_H
#define MYHEADER_H

//add decls here 

#endif

这样,如果您的头文件被包含多次,编译器会忽略它们。

根据经验,如果您包含 B.h 且其中包含 A.h ,那么最好在您的应用程序中包含 A.h 和 B.h,而不是依赖于 B.h 的包含。

也只将声明放入头文件中。

不惜一切代价避免在头文件中定义。


2
投票

您没有说这些相互依赖是什么,所以这些只是猜测。在所有这些中,我假设 A.h 定义了

class A
,B.h 定义了
class B

情况 1:相互依赖是通过指针或引用实现的。
例如,

class A
包含类型为
B*
的数据成员,反之亦然。在这种情况下,两个标头都不需要
#include
另一个标头。请改用前向声明。

情况2:通过对象相互依赖。
例如,

class A
包含类型为
B
的数据成员,反之亦然。在这种情况下,你就完蛋了。

案例 3:混合依赖关系。
例如,

class A
包含类型为
B
的数据成员,但
class B
包含类型为
A*
的数据成员。现在 A.h 确实需要
#include B.h
,但 B.h 只需要
class A
的前向声明。

您应该始终使用某种一次性包含防护来防止标头被多次包含。


1
投票

假设在每个标题中你都有一个类,你可以这样做:

头文件:“A.h”

#ifndef A_H
#define A_H
Class B;

Class A {
public:
  B name_of_B_;
}

#endif

使用

#ifndef A_H #define A_H #endif
,您可以确保每个标头仅包含一次。您应该在生成的几乎每个头文件中使用它,而不仅仅是在双重包含的特殊情况下。使用
Class B;
可以声明将在某个地方定义一个名为“B”的类。

Class B {
public:
  A name_of_A_;
}

#endif

与“B”级的故事相同。通过这种方式,您可以避免无限循环包含。


0
投票

你有一个循环依赖。可以使用In Include Guards来解决。


0
投票

尝试添加标头防护,

#ifndef _A_H_
#define _A_H_
...
..
.
#endif /* #ifndef _A_H_ */

你不应该两次包含头文件,这会导致重新定义..


0
投票

当头文件添加到文件中时,它会在编译的预处理部分中包含在内。因此将 B.h 包含到 A.h 中。并将 A.h 包含在 B.h 中。这是一种无限递归,并且文件被包含多次。

将 B.h 包含在 A.h 中等于 A.h <- B.h 将 A.h 包含在 B.h 中等于 Bh <- A.h

所以它是无限递归循环之王。

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