我有一个Component
类,它是父类,例如Sprite
类。Sprite
也有各种各样的动画儿童,但这并不是这个问题的重点。我还有一个组件管理器,它包含一个map<string, Component>
。我将创建的每个组件都存储在此映射中。目前有12种类型的组件,但数量还会增加。
我的Component
类具有virtual void draw()
和update()
函数,在本例中Sprite
也是如此。然而,当我循环遍历组件的映射时,它只调用Component
draw()
和update()
。
我还没有找到一个对我有效的答案。
您正在经历对象切片--由于map
仅按值存储Component
对象,因此这些对象不包括Component
子类提供的任何信息。一般来说,子类型多态性只适用于指针类型,而不适用于值类型。因此,您需要通过指针存储实例,最好是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;
您的问题很常见,它被称为切片。贴图不包含原始对象,而是包含对象的副本。副本不是您试图插入到映射中的类型,而是您为映射声明的基类型。
唯一的解决方法是存储指针,而不是对象本身。通常,这是使用智能指针(如shared_ptr
),因此清除是自动的。
听起来像是切片,请尝试在映射中存储指向组件的指针。