我有一个类GameObject,它有一个Component和Transform向量。Transform是一个组件,但是可以单独访问它。当我试图在GameObject中包含Component.h和Transform.h时,我在Component上得到一个基类未定义的错误。
错误信息:
Error 1 error C2504: 'Component' : base class undefined c:userspyrodocumentsvisual studio 2010projectsenginemaintransform.h 9
GameObject.h
#ifndef _GameObject
#define _GameObject
#include "Core.h"
#include "Component.h"
#include "Transform.h"
class Transform;
class Component;
class GameObject
{
protected:
Transform* transform;
vector<Component*> components;
};
#endif
Component.h
#ifndef _Component
#define _Component
#include "Core.h"
#include "GameObject.h"
class GameObject;
class Component
{
protected:
GameObject* container;
};
#endif
Transform.h
#ifndef _Transform
#define _Transform
#include "Core.h"
#include "Component.h"
//Base class undefined happens here
class Transform : public Component
{
};
#endif
我发现了一堆其他的主题,但他们并没有真正解决我的问题。问题是:为什么我得到这个错误,我如何修复它?
你的代码有几个问题:
1。循环依赖
GameObject.h
包括Component.h
, Component.h
包括GameObject.h
。
这个循环依赖会破坏一切。根据您"从哪个文件开始",GameObject
将不会从Component
中可见,反之亦然,由于包含保护。
移除循环依赖:你根本不需要那些#include
,因为你已经在使用前向声明了。一般来说,尽量减少在头文件中使用#include
。
2。语法错误
当你修复了这个,在Component.h
中添加缺失的};
。
(你对Transform
的定义认为它是Component
内部的嵌套类,在那一点上,还没有完全定义)
3。保留名称
这在今天可能不会给您带来实际问题,但是您的宏名不应该以_
开头,因为这些是为实现(编译器)保留的。
假设某个源文件有#include "Component.h"
指令而没有其他#include
指令。以下是发生的事情,按顺序排列:
- 定义了预处理器符号
_Component
。 - 对
Component.h
中的#include "GameObject.h"
指令进行了扩展。 -
GameObject.h
中的#include "Component.h"
指令被扩展。
这没有任何作用,因为现在已经定义了_Component
。 - 对
GameObject.h
中的#include "Transform.h"
指令进行了扩展。 -
Transform.h
中Transform
类的定义不能编译,因为基类Component
还没有定义。
问题在于您有太多多余的#include
语句。例如,GameObject.h
不需要包含Component.h
。所需要的就是向前声明。一般来说,除非确实需要,否则不要在头文件中包含文件。如果您确实需要这样做,您需要非常小心循环包含。