我有一个GameObject类,它有一个Component和Transform的向量。 Transform是一个Component,但可以自己访问。 当我尝试在GameObject中包含Component.h和Transform.h时,我在Component上遇到Base类未定义错误。
错误讯息:
Error 1 error C2504: 'Component' : base class undefined c:\users\pyro\documents\visual studio 2010\projects\engine\main\transform.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
我发现了很多其他主题,但它们并没有真正解决我遇到的问题。 所以问题是这样的:为什么我会收到此错误以及如何解决?
答案 0 :(得分:9)
您的代码存在一些问题:
GameObject.h
包括Component.h
,Component.h
包含GameObject.h
。
这种循环依赖会破坏一切。根据您从“开始”的文件,由于包含警卫,GameObject
将无法显示Component
,反之亦然。
删除循环依赖:你根本不需要那些#include
,因为你已经在使用前向声明了。一般来说,最小化使用{{1在标题中。
修复后,在#include
中添加丢失的};
。
(您对Component.h
的定义认为它是Transform
内的嵌套类,此时尚未完全定义。)
这可能不会导致您今天遇到实际问题,但您的宏名称不应以Component
开头,因为它们是为实现(编译器)使用而保留的。
答案 1 :(得分:3)
假设某个源文件具有#include "Component.h"
指令而没有其他#include
指令。这是按顺序发生的事情:
_Component
。#include "GameObject.h"
中的Component.h
指令已展开。#include "Component.h"
中的GameObject.h
指令已展开
这没有任何作用,因为现在定义了_Component
。 #include "Transform.h""
中的GameObject.h
指令已展开。Transform
中的类Transform.h
的定义将无法编译,因为尚未定义基类Component
。问题是你有太多多余的#include
陈述。例如,GameObject.h
不需要包含Component.h
。前瞻性声明就是所需要的。通常,除非您确实需要,否则不要在标头中包含文件。如果您确实需要这样做,则需要非常小心圆形夹杂物。