如何在C++游戏引擎中用Vector存储所有GameObject的地址?
问题分析与修复方案
你的代码存在几个关键问题,导致无法正确运行或不符合游戏引擎的设计逻辑:
- 错误的继承关系:GameObject继承Engine完全不合理,Engine是游戏对象的管理者,GameObject是被管理的对象,二者是组合关系而非继承关系(继承代表"是一种",GameObject显然不是Engine的子类)。
- 对象切片风险:用
std::vector<GameObject>存储对象时,后续若创建GameObject的子类(如Player、Enemy),存入容器会发生对象切片,子类特有的数据和方法会丢失。 - 大小写不匹配:主函数中调用的
engine.run()是小写,而Engine类的方法是Run()(大写R),编译会报错。 - 缺失必要依赖:未包含
<vector>等核心头文件,且Engine类使用GameObject时缺少前向声明。
修正后的完整代码示例
基础依赖与前向声明
#include <vector> #include <memory> // 前向声明GameObject,解决类之间的依赖问题 class GameObject;
Engine类(游戏对象管理器)
class Engine { public: Engine() = default; // 使用智能指针存储,避免对象切片并自动管理内存 std::vector<std::unique_ptr<GameObject>> GameObjects; // 接收智能指针的右值,转移所有权到容器 void AddNewObject(std::unique_ptr<GameObject> obj) { GameObjects.push_back(std::move(obj)); } void Run() { // 遍历所有对象并调用Update for (auto& obj : GameObjects) { obj->Update(); } } };
GameObject类(基础游戏对象)
class GameObject { public: GameObject() = default; // 虚析构函数,确保子类对象能正确析构 virtual ~GameObject() = default; // 虚函数,允许子类重写自定义更新逻辑 virtual void Update() { // 默认更新逻辑,可留空或实现基础行为 } };
主函数示例
int main() { Engine engine; // 添加基础GameObject engine.AddNewObject(std::make_unique<GameObject>()); // 示例:创建GameObject子类Player class Player : public GameObject { public: void Update() override { // Player专属的更新逻辑 } }; // 添加Player对象 engine.AddNewObject(std::make_unique<Player>()); engine.Run(); return 0; }
关键优化说明
- 智能指针的使用:
std::unique_ptr既避免了对象切片问题,又无需手动管理内存,容器销毁时会自动释放所有游戏对象。 - 虚函数设计:将
Update设为虚函数,子类可以灵活重写该方法实现个性化逻辑。 - 修正关系模型:移除错误的继承,Engine与GameObject回归"管理-被管理"的合理组合关系。
内容的提问来源于stack exchange,提问作者Parzivil
相关产品推荐
相关产品推荐

