C ++类互相引用(=>错误+字段'...'具有不完整类型)

时间:2011-07-09 11:56:29

标签: c++ class

我的应用程序中的类工作方式如下:Creature包含Action个字段的字段很少。必须运行这些ActionCreature才会调用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中 - 我会在彼此之前使用文件'。

5 个答案:

答案 0 :(得分:8)

Creature类的成员类型为Action。编译器需要知道要编译的Action类的完整定义 - 使用前向声明生成的不完整类型是不够的。

Action类只需要指针到该标头中的Creature对象。在这种情况下,编译器只需要知道将在某个时刻定义Creature

在您的具体情况下,您可以通过颠倒您声明课程的顺序来逃避。

(即Creature中的前向声明action.haction.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