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

C++ classes refer to each other ( => error + field '...' has incomplete type)

本文关键字:字段 类型 错误 引用 gt C++      更新时间:2023-10-16

我的应用程序中的类是这样工作的:CreatureAction s有几个字段。当这些Action必须运行时,Creature调用someActionField->do(this)。Action有方法viod do(Creature* cr)以及关于如何使用该Creature的所有信息。

所以,生物必须有Action字段,并且知道Actiondo方法。Action必须知道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中,我将使用文件"优先"

您的Creature类有类型为Action的成员。编译器需要知道Action类的完整定义才能编译它——由前向声明生成的不完整类型是不够的。

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

在你的特殊情况下,你可以改变你声明类的顺序。

(即。

action.h中前声明Creature,在creature.h中包含action.h)

in action.h put class Creature; and #include "action.h"

对于指针,你不需要完整的定义,因为它只是一个指针,编译器可以为它生成"代码"。如果你使用一个简单的类/结构,编译器必须知道它的类型,因为它需要知道它的大小。

正向声明一个类型时,编译器只知道这个类型存在;它不知道它的大小、成员或方法,因此称为不完全类型

不能使用不完整类型来声明成员(因为编译器在声明时需要知道类型的大小),因此会得到错误。

你不需要在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)的函数

  • 不能声明不完整类型的成员。

creature.h必须包含action.h,因为它声明了Action类型的成员。

你不需要在action.h中#include "creature.h"。您所需要的只是向前声明类Creature。你需要在creature.h中#include " Action. h",因为onHit和onDie都是Action的实例。

使用引用或指针:

     #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