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

时间:2021-11-08 14:04:56

Classes in my application work like this: Creature has few fields with Actions. When these Actions must be run Creature calls someActionField->do(this). Action has method viod do(Creature* cr) and all information about what to do with this Creature.

我的应用程序中的类工作方式如下:Creature几乎没有使用Actions的字段。当必须运行这些Actions时,Creature会调用someActionField-> do(this)。动作有方法viod do(Creature * cr)以及关于如何对这个生物做什么的所有信息。

So, Creature must have Action field and know that Action has do method. Action must know that Creature has such fields like: Will, HP, etc...

所以,Creature必须有Action字段并且知道Action有做法。动作必须知道Creature有以下字段:Will,HP等......

I've got

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

And action.h

#include "creature.h"

namespace Core
{


class Action
{
public:
Action();
virtual void _do(Creature* cr);
virtual ~Action();
};

But in this case field `onDie' has incomplete type error appears. If I include action.h into creature.h - I use files 'before each other'.

但在这种情况下,字段“onDie”出现不完整的类型错误。如果我将action.h包含在creature.h中 - 我会在彼此之前使用文件'。

5 个解决方案

#1


8  

You Creature class has members of type Action. The compiler needs to know the full definition of the Action class to compile that - an incomplete type as produced with a forward declaration is not enough.

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

The Action class only requires a pointer to a Creature object in that header. In that case, the compiler only needs to know that Creature will be defined at some point.

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

In your specific case, you could get away with inverting the order in which you declare your classes.

在您的具体情况下,您可以通过反转声明类的顺序来逃避。

(i.e. forward-declare Creature in action.h, and include action.h in creature.h)

(即在action.h中正向声明生物,并在creature.h中包含action.h)

#2


3  

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

在action.h中放置类生物;在另一个#include“action.h”

For pointers you don't need complete definition because it's just a pointer and the compiler can generate "code" for it. If you use a simple class/struct the compiler has to have knowledge of the type because it needs to know how big it is.

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

#3


3  

When you forward declare a type, all the compiler know is that this type exists; it knows nothing about its size, members, or methods, hence it is called an Incomplete Type

当你转发声明一个类型时,所有编译器都知道这个类型存在;它对它的大小,成员或方法一无所知,因此它被称为不完全类型

You cannot use an incomplete type to declare a member(because compile needs to know the size of the type while declaring it) and hence you get the error.

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

You don't need to #include "creature.h" in action.h but you just need to forward declare class Creature. You do need to #include "action.h" in creature.h

你不需要在action.h中#include“creature.h”,但你只需要转发声明类Creature。你需要在creature.h中#include“action.h”

Your header files should have the following construct:

您的头文件应具有以下构造:

creature.h

#include "effect.h"
#include "action.h"
#include "heedupdate.h"

action.h

class creature;

This makes use of two rules:

这使用了两个规则:

  • One can Declare functions or methods which accepts/return incomplete types:
  • 可以声明接受/返回不完整类型的函数或方法:

action.h only declares a function which accepts an Incomplete type(Creature)

action.h只声明一个接受不完整类型的函数(生物)

  • One cannot declare a member to an incomplete type.
  • 无法将成员声明为不完整类型。

creature.hhas to include action.h because it declares a member of type Action.

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

#4


2  

You don't need to #include "creature.h" in action.h. All you need is a forward declaration of class Creature. You do need to #include "action.h" in creature.h because onHit and onDie are instances of Action.

你不需要在action.h中#include“creature.h”。你所需要的只是类生物的前向声明。你需要在creature.h中#include“action.h”,因为onHit和onDie是Action的实例。

#5


0  

Use references, or pointers :

使用引用或指针:

     #include "effect.h"
     #include "heedupdate.h"

     namespace Core
     {

     class Action;

     class Creature : public NeedUpDate
     {
     public:
         virtual ~Creature();
         int HP;
         Action & onHit;
         Action & onDie;
    // ...


     };

     }

#endif

This way you can break dependencies and not need a fully declared Action class

这样您就可以破坏依赖关系而不需要完全声明的Action类

#1


8  

You Creature class has members of type Action. The compiler needs to know the full definition of the Action class to compile that - an incomplete type as produced with a forward declaration is not enough.

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

The Action class only requires a pointer to a Creature object in that header. In that case, the compiler only needs to know that Creature will be defined at some point.

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

In your specific case, you could get away with inverting the order in which you declare your classes.

在您的具体情况下,您可以通过反转声明类的顺序来逃避。

(i.e. forward-declare Creature in action.h, and include action.h in creature.h)

(即在action.h中正向声明生物,并在creature.h中包含action.h)

#2


3  

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

在action.h中放置类生物;在另一个#include“action.h”

For pointers you don't need complete definition because it's just a pointer and the compiler can generate "code" for it. If you use a simple class/struct the compiler has to have knowledge of the type because it needs to know how big it is.

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

#3


3  

When you forward declare a type, all the compiler know is that this type exists; it knows nothing about its size, members, or methods, hence it is called an Incomplete Type

当你转发声明一个类型时,所有编译器都知道这个类型存在;它对它的大小,成员或方法一无所知,因此它被称为不完全类型

You cannot use an incomplete type to declare a member(because compile needs to know the size of the type while declaring it) and hence you get the error.

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

You don't need to #include "creature.h" in action.h but you just need to forward declare class Creature. You do need to #include "action.h" in creature.h

你不需要在action.h中#include“creature.h”,但你只需要转发声明类Creature。你需要在creature.h中#include“action.h”

Your header files should have the following construct:

您的头文件应具有以下构造:

creature.h

#include "effect.h"
#include "action.h"
#include "heedupdate.h"

action.h

class creature;

This makes use of two rules:

这使用了两个规则:

  • One can Declare functions or methods which accepts/return incomplete types:
  • 可以声明接受/返回不完整类型的函数或方法:

action.h only declares a function which accepts an Incomplete type(Creature)

action.h只声明一个接受不完整类型的函数(生物)

  • One cannot declare a member to an incomplete type.
  • 无法将成员声明为不完整类型。

creature.hhas to include action.h because it declares a member of type Action.

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

#4


2  

You don't need to #include "creature.h" in action.h. All you need is a forward declaration of class Creature. You do need to #include "action.h" in creature.h because onHit and onDie are instances of Action.

你不需要在action.h中#include“creature.h”。你所需要的只是类生物的前向声明。你需要在creature.h中#include“action.h”,因为onHit和onDie是Action的实例。

#5


0  

Use references, or pointers :

使用引用或指针:

     #include "effect.h"
     #include "heedupdate.h"

     namespace Core
     {

     class Action;

     class Creature : public NeedUpDate
     {
     public:
         virtual ~Creature();
         int HP;
         Action & onHit;
         Action & onDie;
    // ...


     };

     }

#endif

This way you can break dependencies and not need a fully declared Action class

这样您就可以破坏依赖关系而不需要完全声明的Action类