【问题标题】:Mutual include in C++ .. how does it work? [duplicate]C++ 中的相互包含 .. 它是如何工作的? [复制]
【发布时间】:2011-07-22 13:35:29
【问题描述】:

可能重复:
Proper way to #include when there is a circular dependency?

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

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

【问题讨论】:

  • 好问题。预处理器逐行工作,您将研究#ifdef#define#endif 的工作原理:-)

标签: c++ include header-files


【解决方案1】:

在头文件中使用 Include 保护。 http://en.wikipedia.org/wiki/Include_guard

#ifndef MYHEADER_H
#define MYHEADER_H

//add decls here 

#endif

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

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

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

    【讨论】:

    • 谢谢@Nicol,这是一个很好的观点。一般来说(不是在这种双重包含的特定情况下),您能否解释一下为什么您更喜欢前向声明而不是正常包含?
    【解决方案3】:

    你没有说这些相互依赖是什么,所以这些只是猜测。在所有这些中,我假设 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 的前向声明。

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

    【讨论】:

      【解决方案4】:

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

      头文件:“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”类的故事相同。这样可以避免无限循环包含。

      【讨论】:

      • 每个头文件末尾的包含完全没有用。前向声明,例如 A 类;是一种告诉编译器稍后将出现 A 类的机制,对于 B 类也是如此。此时,何时解析 A 类或 B 类都无关紧要,因为您只是告诉编译器它们通过使用前向声明,它们都将在编译结束时出现。因此,可以删除头文件末尾的包含,因为它们没有任何作用。问候;)
      • 对!感谢您指出。
      【解决方案5】:

      您有一个Circular Dependency。可以使用Include Guards 解决。

      【讨论】:

        【解决方案6】:

        尝试添加标题保护,

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

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

        【讨论】:

          【解决方案7】:

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

          在 A.h 中包含 B.h 等于 A.h 在 B.h 中包含 A.h 等于 Bh

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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-07-17
            • 2010-09-28
            • 1970-01-01
            • 2011-07-22
            • 2019-10-02
            • 2013-07-18
            • 1970-01-01
            相关资源
            最近更新 更多