【问题标题】:C++ circular header includes [duplicate]C ++循环标头包括[重复]
【发布时间】:2012-08-11 20:56:29
【问题描述】:

我知道之前有人问过与此类似的问题,但经过研究,我仍然对循环标题包含有疑问。

//FooA.h
#ifndef H_FOOA
#define H_FOOA

#include "foob.h"

class FooA{
   public:
      FooB *fooB;
};


//FooB.h
#ifndef H_FOOB
#define H_FOOB

class FooA;
class FooB{
   public:
      FooA *fooA;
};

现在,如果我有两个循环依赖项,这就是我在 stackoverflow 上看到人们解决问题的方式。我唯一的问题是,在我的 main.cpp 中,我必须先包含 fooa.h,然后再包含 foob.h

//main.cpp the right way
#include "fooa.h"
#include "foob.h"

//main.cpp that will surely get a compile error
#include "foob.h"
#include "fooa.h"

现在我的问题是“有没有一种方法可以转发声明这些类,让我不必关心在 main.cpp 中包含头文件的顺序?”

【问题讨论】:

  • 正如答案所指出的,您可以在两个文件中使用前向声明。如果情况比较复杂,你可以从foob.h#include "fooa.h",这样可以保证你想要的包含顺序。
  • 示例代码的包含中没有任何循环。如果您添加缺少的#endif,一切都很好。你得到什么编译错误?

标签: c++ header header-files circular-dependency


【解决方案1】:

有没有一种方法可以转发声明这些类,让我不必关心在 main.cpp 中包含头文件的顺序?

由于您只处理简单的指针,您可以在这两种情况下使用前向声明:

FooA.h

#ifndef H_FOOA
#define H_FOOA

// #include "foob.h" << not needed!
class FooB;       // << substitute with a forward declaration of FooB

class FooA{
   public:
      FooB *fooB;
};
#endif

FooB.h

#ifndef H_FOOB
#define H_FOOB

class FooA;
class FooB{
   public:
      FooA *fooA;
};
#endif

【讨论】:

  • @user1600812 完全正确,main 可以包含它需要的文件——使用这个例子,顺序无关紧要。
  • 我想我忘了在我的具体代码中提到这一点。 fooa.h forward 声明自己,因为我的代码中有几个自引用指针。在我的具体情况下,我认为你不能按照自己的方式去做,因为我会提前两次声明一个班级。但是,在我上面制作的示例中,您的解决方案有效。谢谢。
  • @user1600812 C++ 允许多个前向声明(例如在单独的文件中)。
  • @user1600812 - 同一个文件中的多个前向声明只要一致就没有问题。
【解决方案2】:

您不必关心顺序,因为fooa.h 包含foob.h,而foob.h 具有FooA 的前向声明。您的代码中的一切都已正确。

【讨论】:

  • 对缺失的#endif 取模,发布的代码完全没有问题。也没有循环,这让我怀疑缺少什么。
【解决方案3】:

由于这两个类都只包含一个指针,因此您不需要包含另一个标头。前向声明就可以了。

实际使用其他类的任何代码需要标头,但它应该在 cpp 文件中。

【讨论】:

    【解决方案4】:

    在两个头文件中使用前向声明。

    你知道你可以在同一行声明它吗?

    在“FooB.h”中

    class FooB{
        public:
            class FooA *fooA;
    };
    

    在“FooA.h”中

    class FooA {
        public:
            class FooB *fooB;
    };
    

    【讨论】:

    • 不会分别向前引用 FooB::FooA 和 FooA::FooB 吗?
    猜你喜欢
    • 2011-07-11
    • 2010-12-11
    • 2015-02-03
    • 2012-09-16
    • 2012-03-24
    • 1970-01-01
    • 2011-06-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多