我的应用程序中的类工作方式如下:Creature
包含Action
个字段的字段很少。必须运行这些Action
时Creature
才会调用someActionField->do(this)
。操作方法viod do(Creature* cr)
以及有关如何处理此Creature
的所有信息。
因此,Creature必须拥有Action
字段并知道Action
具有do
方法。行动必须知道Creature
有以下字段:Will,HP等...
我有
creature.h
#include "effect.h"
#include "heedupdate.h"
namespace Core
{
class Action;
class Creature : public NeedUpDate
{
public:
virtual ~Creature();
int HP;
Action onHit;
Action onDie;
// ...
};
}
#endif
和action.h
#include "creature.h"
namespace Core
{
class Action
{
public:
Action();
virtual void _do(Creature* cr);
virtual ~Action();
};
但在这种情况下,会出现字段`onDie' has incomplete type
错误。如果我将action.h包含在creature.h中 - 我会在彼此之前使用文件'。
答案 0 :(得分:8)
您Creature
类的成员类型为Action
。编译器需要知道要编译的Action
类的完整定义 - 使用前向声明生成的不完整类型是不够的。
Action
类只需要指针到该标头中的Creature
对象。在这种情况下,编译器只需要知道将在某个时刻定义Creature
。
在您的具体情况下,您可以通过颠倒您声明课程的顺序来逃避。
(即Creature
中的前向声明action.h
,action.h
中包含creature.h
答案 1 :(得分:3)
在action.h中放置class Creature;
,在另一个放置#include "action.h"
对于指针,您不需要完整的定义,因为它只是一个指针,编译器可以为它生成“代码”。如果你使用一个简单的类/结构,编译器必须知道类型,因为它需要知道它有多大。
答案 2 :(得分:3)
当您 转发声明 类型时,所有编译器都知道此类型存在;它对其大小,成员或方法一无所知,因此称为 不完整类型
您不能使用不完整的类型来声明成员(因为编译时需要知道类型的大小),因此您会收到错误。
你不需要在action.h中#include“creature.h”,但你只需要转发声明类Creature。你需要在creature.h中#include“action.h”
您的头文件应具有以下构造:
<强> creature.h 强>
#include "effect.h"
#include "action.h"
#include "heedupdate.h"
<强> action.h 强>
class creature;
这使用了两个规则:
action.h
仅声明一个接受不完整类型(生物)的函数
creature.h
必须包含action.h
,因为它声明了Action
类型的成员。
答案 3 :(得分:2)
你不需要在action.h中#include“creature.h”。您所需要的只是类Creature的前向声明。你需要在creature.h中#include“action.h”,因为onHit和onDie是Action的实例。
答案 4 :(得分:0)
使用引用或指针:
#include "effect.h"
#include "heedupdate.h"
namespace Core
{
class Action;
class Creature : public NeedUpDate
{
public:
virtual ~Creature();
int HP;
Action & onHit;
Action & onDie;
// ...
};
}
#endif
这样您就可以破坏依赖关系而不需要完全声明的Action
类