所有继承自同一个类的对象的映射,调用对象方法而不是父对象; C ++

时间:2012-07-31 20:41:10

标签: c++ inheritance virtual-functions

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

我的Component课程有virtual void draw()update()个功能,在这种情况下,Sprite的功能相同。但是,当我遍历组件地图时,它只会调用Component draw()update()

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

3 个答案:

答案 0 :(得分:1)

您遇到object slicing - 由于您的map仅按值Component存储Component个对象,因此这些对象不包含{{1>}提供的任何信息{1}}子类。一般来说,子类型多态只能通过指针类型而不是值类型来工作。因此,您需要通过指针存储实例,最好是std::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();

确保在清理期间delete Component个对象,例如,在组件管理器的析构函数中。 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;

答案 1 :(得分:1)

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

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

答案 2 :(得分:0)

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