C ++ classes relate to each other (=> error + field "..." has an incomplete type)

The classes in my application work as follows: Creature has several fields with Action s. When these someActionField->do(this) to be launched by Creature , calls someActionField->do(this) . The action has a viod do(Creature* cr) method and all the information on what to do with this Creature .

So, the creature must have an Action field and know that Action has a do method. The action should know that Creature has fields such as: Will, HP, etc.

I have

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, the `onDie' has incomplete type field appears. If I include action.h in creature.h - I use the files "in front of each other."

+4
source share
5 answers

The Creature class has members of type Action . The compiler must know the full definition of the Action class to compile what is not an incomplete type created using a direct declaration.

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

In your particular case, you can 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 )

+8
source

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

For pointers, you do not need a complete definition, because it is just a pointer, and the compiler can generate "code" for it. If you use a simple / struct class, the compiler must know this type because it needs to know how big it is.

+3
source

When you forward to declare a type, all compilers know that this type exists; he knows nothing about his size, members or methods, so he is called the Incomplete type

You cannot use an incomplete type to declare a member (since compilation must know the size of the type when declaring it), and therefore you get an error.

You do not need to # include "creature.h" in action.h, but you just need to send the Creature class declaration. You need # to include "action.h" in creature.h

Your header files should have the following structure:

creature.h

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

action.h

 class creature; 

This uses two rules:

  • You can declare functions or methods that accept / return incomplete types:

action.h declares only a function that takes an incomplete type (Creature)

  • You cannot declare a member an incomplete type.

creature.h should include action.h as it declares a member of type Action .

+3
source

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

+2
source

Use links 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 the dependencies and not need a fully declared Action class

0
source

All Articles