2012-07-31 113 views
2

我有一个Component类,它是父类,例如Sprite类。 Sprite也有各种儿童动画,但这不是这个问题的重点。我也有一个组件经理,持有map<string, Component>。我存储了我在该地图中创建的每个组件。目前有12种类型的组件,但会增加。所有从同一个类继承的对象映射,调用对象方法而不是父对象; C++

我的Component类有virtual void draw()update()功能,在这种情况下Sprite也是一样。但是,当我循环查看组件图时,它只调用Componentdraw()update()

我还没有真正能够找到一个实际上为我工作的答案呢。

+2

你在地图或对象中存储指针吗?你真的应该存储指针,否则你会遇到'对象切片'问题,这与你描述的症状完全相同。 – jahhaj 2012-07-31 20:42:54

回答

1

你的价值经历object slicing - 由于你的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(); 

并确保您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; 
+0

感谢您的帮助和解释与例子。 – Baraphor 2012-08-02 13:47:24

0

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

1

您的问题是相当普遍的,这就是所谓的切片。该地图不包含原始对象,它包含副本的对象。该副本不是您尝试插入地图的类型,而是您为地图声明的基本类型。

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