在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继续。
编辑:两者现在都解决了。
答案 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
的前向声明,编译器不知道它的组成也不知道其中的成员,编译器只知道Stage
是type
。从而,
Stage
是编译器的不完整类型。对于不完整的类型,无法创建它的对象或执行任何需要编译器知道Stage
的布局或更多Stage
只是一种类型的事实。由于指向所有对象的指针只需要相同的内存分配,因此只需将Stage
作为指针引用即可使用前向声明。
您可以使用前向声明来克服循环依赖性问题。
答案 1 :(得分:5)
这是循环依赖。不要制作它们。您可以通过使用#include "Stage.h"
的前向声明(即Stage
)替换stuffcollection.h中的class Stage;
来解决此问题。
答案 2 :(得分:3)
您可以使用前向声明,而不是#include
,而不是class Stage;
和class Stuffcollection
。它还具有减少依赖性的好处。