双包括解决方案?

时间:2011-10-05 18:29:05

标签: c++ include include-guards

在C ++中,我遇到了双重包含问题:

文件stuffcollection.h

#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H

#include "Stage.h"

class Stuffcollection {
    public:
        bool myfunc( Stage * stage );
};

#endif // STUFFCOLLECTION_H

文件stage.h:

#pragma once
#ifndef STAGE_H
#define STAGE_H

#include "Stuffcollection.h"

class Stage {
    // stuffcollection used in stage.cpp
};

#endif // STAGE_H

编译器错误:

\Stuffcollection.h|(line were bool myfunc is declared)|error: 'Stage' has not been declared| ||=== Build finished: 1 errors, 0 warnings ===|

有人可以解释为什么会发生这种情况以及如何解决这个问题?我已经使用了包含警戒和pragma一次预处理程序指令,它只是不起作用。

(如果我从stage.h中删除#include "Stuffcollection.h"并注释掉在stage.cpp中使用它的相应行,我的其余代码工作正常。这恰好就是当Stuffcollection包含在舞台中时突然停止工作。)

PS:舞台只是一个例子,我在几乎所有其他文件中都使用了stuffcollection,每次我都遇到这个问题。

编辑:我按照建议进行了操作,现在问题是invalid use of incomplete type,即虽然给出的答案解决了循环依赖的问题,但他们并没有解决我的问题处理。我的问题在Circular Dependencies / Incomplete Types继续。

编辑:两者现在都解决了。

3 个答案:

答案 0 :(得分:13)

您有循环依赖。而是在Stuffcollection.h

中使用转发声明
#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H

//#include "Stage.h"      //<------------------Don't Do This
class Stage;              //<------------------Do This

class Stuffcollection {
    public:
        bool myfunc( Stage * stage );
};

#endif // STUFFCOLLECTION_H

<强>理由:
您可以使用上面代码段中的转发声明,因为Stuffcollection.h仅使用指向Stage的指针。

<强>解释
使用类Stage的前向声明,编译器不知道它的组成也不知道其中的成员,编译器只知道Stagetype。从而, Stage是编译器的不完整类型。对于不完整的类型,无法创建它的对象或执行任何需要编译器知道Stage的布局或更多Stage只是一种类型的事实。由于指向所有对象的指针只需要相同的内存分配,因此只需将Stage作为指针引用即可使用前向声明。

您可以使用前向声明来克服循环依赖性问题。

进一步阅读:
When to use forward Declarations?

答案 1 :(得分:5)

这是循环依赖。不要制作它们。您可以通过使用#include "Stage.h"的前向声明(即Stage)替换stuffcollection.h中的class Stage;来解决此问题。

答案 2 :(得分:3)

您可以使用前向声明,而不是#include,而不是class Stage;class Stuffcollection。它还具有减少依赖性的好处。

相关问题