Classes in my application work like this: Creature
has few fields with Action
s. When these Action
s 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.h
has 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.h
has 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类