【问题标题】:Header files and multiple class usage (EDIT: forward declarations)头文件和多类使用(编辑:前向声明)
【发布时间】:2013-02-09 21:07:41
【问题描述】:

我有一个问题,我有多个头文件,我需要将它们中的每一个都包含在彼此中。显然,这是做不到的,因为当我编译时,会抛出“包含嵌套太深”的错误 - 因为这实际上要求编译器进入无限包含循环。

我可以使用 void 指针来修复它,但这对我来说似乎是一种糟糕的编码习惯。

这是我正在尝试做的一个示例,以帮助理解:

文件-A:

#include "File-B"
#include "File-C"
class A
{
    public: B* p_B;
    public: C* p_C;
};

文件-B:

#include "File-A"
#include "File-C"
class B
{
    public: A* p_A;
    public: C* p_C;
};

文件-C:

#include "File-B"
class C
{
    public: B* p_B;
};

这只是显示需要每个类声明的位置。 void* 肯定有更好的解决方案。

编辑:我已经在使用包含守卫,这段代码只是为了帮助您了解我想要做什么。

【问题讨论】:

    标签: c++ file class header include


    【解决方案1】:

    我会使用包含保护,它只包含某个文件一次。

    #ifndef FILE_A
    #define FILE_A
    class A
    {
        public: B* p_B;
        public: C* p_C;
    };
    #endif
    

    http://en.wikipedia.org/wiki/Include_guard

    每个文件只包含一次头文件。 你也可以使用#pragma_once,虽然它不是标准的。

    在不起作用的情况下,可以使用前向声明。

    class B;
    class C;
    class A
    {
        public: B* p_B;
        public: C* p_C;
    };
    

    【讨论】:

    • 你可能已经切换了。首先使用前向声明,然后包含文件。当访问或引用其他类中的任何内容时,需要类定义。
    【解决方案2】:

    你应该使用include guards

    #ifndef _FILE_A_H_
    #define _FILE_A_H_
    
    // Contents of FileA.h...
    
    #endif
    

    还可以使用 forward declarations 来打破数据结构定义之间的循环依赖关系。

    FileA.h:

    class B; // No need to #include "FileB.h"
    
    class A
    {
    public:
        B* pB;
    };
    

    FileB.h:

    class A; // No need to #include "FileA.h"
    
    class B
    {
    public:
        A* pA;
    };
    

    【讨论】:

    • 似乎投反对票的人对所有试图回答这个问题的人感到不安......
    • 嗨,前向声明是我正在寻找的,谢谢,我会在一秒钟内接受这个答案......
    • @EdwardBird:这会阻止你接受它吗?这不是错误的信息
    • @AndyProwl 没有错,只是与解决方案无关。
    • @EdwardBird:好吧,在你编辑了你的问题之后提到你确实有包含警卫,即使你的代码没有显示它,也许它不再相关。但是我认为那里的信息不会使答案不可接受
    【解决方案3】:

    这就是为什么你有#include <> 守卫。

    #ifndef _FILE_B
    #define _FILE_B
    #include "File-A"
    #include "File-C"
    class B
    {
        public: A* p_A;
        public: C* p_C;
    };
    #endif
    

    【讨论】:

    • 他大概不想回答这个问题。他都对他们投了反对票。
    • 嗯,否决我们是他的权利,我认为我们不应该仅仅为了剥夺他的投票权而这样做。另一方面,我真的很想知道他的原因。
    • @AndyProwl 我认为没有理由投反对票。你说的没有错,我也没有说错。我已经看到这种匿名的“大规模”反对票的上升。我称他们为“愤怒的反对者”。
    • 看来广告出于某种原因决定放过我。我只能想象他是OP,同时考虑到一致的rep波动。但当然不必如此
    • AD 似乎不是 OP,OP 并没有因为 DVing 我们所有人而获得负分。既然如此,OP似乎是无辜的@AndyProwl
    【解决方案4】:

    如果你使用的是指向其他类的指针或引用,并且头文件中没有代码,你可以使用前向声明:

    class A; // Forward declaration
    
    class C; // Forward declaration
    
    class B
    {
      public:
        A* p_A;
        C* p_C;
    };
    

    如果头文件中的代码引用其他类的任何成员,则必须包含其他类的完整定义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-24
      • 2013-10-01
      • 1970-01-01
      相关资源
      最近更新 更多