2

我有一个类 GameObject,它有一个 Component 和 Transform 的向量。Transform 是一个组件,但可以单独访问。当我尝试在 GameObject 中同时包含 Component.h 和 Transform.h 时,我在 Component 上收到 Base class undefined 错误。

错误信息:

    Error   1   error C2504: 'Component' : base class undefined c:\users\pyro\documents\visual studio 2010\projects\engine\main\transform.h 9

游戏对象.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

组件.h

    #ifndef _Component
    #define _Component

    #include "Core.h"
    #include "GameObject.h"

    class GameObject;

    class Component
    {
    protected:
        GameObject* container;
    };
    #endif

变换.h

    #ifndef _Transform
    #define _Transform

    #include "Core.h"
    #include "Component.h"

    //Base class undefined happens here
    class Transform : public Component
    {
    };

    #endif

我发现了很多其他主题,但它们并没有真正解决我遇到的问题。所以问题是这样的:为什么我会收到这个错误,我该如何解决?

4

2 回答 2

9

您的代码有几个问题:


1.循环依赖

GameObject.h包括Component.hComponent.h包括GameObject.h

这种循环依赖破坏了一切。根据您“从哪个文件开始”,由于包含防护,要么GameObject将不可见,Component反之亦然。

删除循环依赖:您根本不需要那些#includes,因为您已经在使用前向声明。通常,尽量减少使用#includein 标头。


2.语法错误

修复后,添加缺少};Component.h.

(您的定义Transform认为它是一个嵌套类Component,此时尚未完全定义。)


3. 保留名称

今天这可能不会给您带来实际问题,但是您的宏名称不应该以这些名称开头,_因为它们是为实现(编译器)使用而保留的。

于 2013-01-05T22:47:10.893 回答
3

假设某个源文件有一个#include "Component.h"指令而没有其他#include指令。这是发生的事情,按顺序:

  1. 预处理器符号_Component已定义。
  2. 中的#include "GameObject.h"指令Component.h被扩展。
  3. 中的#include "Component.h"指令GameObject.h被扩展。
    这没有任何作用,因为_Component现在已定义。
  4. 中的#include "Transform.h"指令GameObject.h被扩展。
  5. 由于尚未定义基类,因此类Transformin的定义Transform.h不会编译。Component

问题是你有太多多余的#include陈述。例如,不需要GameObject.h包含Component.h. 前向声明就是所需要的。通常,除非您确实需要,否则不要在标题中包含文件。如果确实需要这样做,则需要非常小心圆形夹杂物。

于 2013-01-05T22:50:47.723 回答