【发布时间】:2015-01-29 07:16:04
【问题描述】:
我正在用 C++ 制作游戏。在这个游戏中,有一个 GameObject 指针列表。 GameObject 是世界上每个可能与之交互的对象的基类。 Main 的工作是充当裁判,因此它通知每个对象有关碰撞、渲染它们、删除它们等。
玩家的角色有能力。某些技能可能会产生投射物。每个射弹都是不同的,但都派生自 GameObject。必须将它们添加到列表中,以便 main 可以看到它们。我希望 GameObject 指针列表是全局的,以便对象可以将自己推送到列表中,但 main 仍然可以看到并更新它们。就目前而言,如果列表是在 main 中创建的,那么游戏就会运行。
有 3 种可能的解决方案:我将这个列表放在 Globals.h 中,我将单例模式应用于 GameObject 类,或者我把这个列表放在 GameObject.h 中,但在 GameObject 类之外。所有解决方案都会导致错误。
我相信解决方案 1 会导致循环依赖,因为 Globals.h 定义了 GameObject 类所需的枚举值,但列表由 GameObject 指针组成。列表中的第一个错误是“GameObject is undeclared identifier”,并出现在 Globals 中。
//Globals.h
#include "GameObject.h"
#include <list>
std::list<GameObject *> objects;
enum Id{ENEMY, PLAYER, ROCK};
//GameObject.h
#pragma once
#include "Globals.h"
class GameObject{
public:
GameObject();
~GameObject();
Id id;
};
对于解决方案 2,如果我在 GameObject 类中有列表,我可以编译,但是一旦我尝试将自己推送到列表中,链接器就会抛出错误。它说“未解决的外部符号”。如果对象本身也是一个指针,也不会改变。
//GameObject.h
#pragma once
#include "Globals.h"
#include <list>
class GameObject{
public:
static std::list <GameObject *> objects;
GameObject();
~GameObject();
void init(){ objects.push_back(this); }
Id id;
};
对于最终解决方案,链接器告诉我 main.obj 已经定义了列表对象符号。找到一个或多个乘法符号。
//GameObject.h
#pragma once
#include "Globals.h"
#include <list>
class GameObject{
public:
GameObject();
~GameObject();
Id id;
};
std::list <GameObject *> objects;
我已经完全没有想法了,我真的需要这个列表可以访问。解决方案 1 是最可取的,其次是 2,然后是 3。如何使此列表全局可访问?是否可以?有没有比我试过的 3 种方法更好的方法?
更新:如果我使用前向声明和 extern 关键字,解决方案 1 将编译,但是当我尝试时
GameObject *test = new GameObject
objects.push_back(test);
主要,我得到一个未解决的外部。
【问题讨论】:
-
让我想起了 Badass Bubble Battle Boids 游戏:github.com/seanmiddleditch/BubbleBattleBoids 它使用了自己的链表实现(
next成员和静态head和tail在构造函数和我认为是析构函数)。
标签: c++ list linker-errors circular-dependency