2

我有一个Component类,它是父类,例如一个Sprite类。Sprite动画也有各种各样的孩子,但这不是这个问题的重点。我还有一个组件管理器,它拥有一个map<string, Component>. 我将创建的每个组件都存储在此地图中。目前有 12 种类型的组件,但会增加。

我的Component班级有virtual void draw()update()功能,Sprite在这种情况下也是如此。但是,当我遍历组件映射时,它只调用Component draw()and update()

我还没有真正找到真正对我有用的答案。

4

3 回答 3

1

您正在体验对象切片——由于您map按值Component存储对象,因此这些对象不包含子类提供的任何信息。一般来说,子类型多态只通过指针类型起作用,而不是值类型。因此,您需要通过指针存储实例,最好是:Componentstd::map<std::string, std::unique_ptr<Component>>

components["example"] = std::unique_ptr<Component>(new Example());

如果您使用的是非 C++11 编译器,请使用std::map<std::string, Component*>

components["example"] = new Example();

并确保在清理期间您deleteComponent对象,例如,在您的组件管理器的析构函数中。C++03:

for (std::map<std::string, Component*>::const_iterator i = components.begin();
    i != components.end(); ++i)
    delete i->second;

C++11:

for (const auto& i : components)
    delete i.second;
于 2012-07-31T20:51:13.857 回答
1

您的问题很常见,称为slicing。地图不包含原始对象,它包含对象的副本。副本不是您尝试插入地图的类型,它是您为地图声明的基本类型。

解决这个问题的唯一方法是存储指针而不是对象本身。通常这是使用智能指针,例如shared_ptr自动清理。

于 2012-07-31T20:52:31.917 回答
0

对我来说听起来像是切片,尝试在地图中存储指向组件的指针。

于 2012-07-31T20:44:42.180 回答