3

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

文件 stuffcollection.h

#pragma once
#ifndef STUFFCOLLECTION_H
#define STUFFCOLLECTION_H

#include "Stage.h"

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

#endif // STUFFCOLLECTION_H

文件阶段.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 once 预处理器指令,但它不起作用。

(如果我#include "Stuffcollection.h"从 stage.h 中删除并注释掉在 stage.cpp 中使用它的相应行,我的其余代码工作正常。实际上只是在将 Stuffcollection 包含到阶段时它突然停止工作。)

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

编辑:我遵循了建议,现在问题是invalid use of incomplete type,即虽然给出的答案解决了循环依赖的问题,但它们并没有解决我正在处理的问题。我的问题在Circular Dependencies / Incomplete Types中继续存在。

编辑:现在都解决了。

4

3 回答 3

14

你有一个循环依赖。而是使用前向声明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,编译器不知道它的组成也不知道它里面的成员,编译器只知道它Stage是一个type。因此, 对于编译器来说,Stage是一个不完整的类型。使用 Incomplete types ,人们不能创建它的对象或做任何需要编译器知道布局的事情,或者不仅仅是一个类型Stage的事实。Stage由于指向所有对象的指针只需要相同的内存分配,因此您可以在仅引用Stage指针时使用前向声明。

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

进一步阅读:
何时使用前向声明?

于 2011-10-05T18:31:19.717 回答
6

这是一个循环依赖。不要制造它们。您可以通过将#include "Stage.h"stuffcollection.h 中的前向声明替换为Stage(ie class Stage;) 来解决这个问题。

于 2011-10-05T18:31:04.320 回答
3

#include您可以使用前向声明代替ieclass Stage;class Stuffcollection. 它还具有减少依赖性的好处。

于 2011-10-05T18:31:06.647 回答