map迭代器擦除不调用适当的析构函数

时间:2012-02-25 11:59:57

标签: c++ sfml stdmap

gameObjectsstd::map<sf::String,VisibleGameObject*>resultsstd::map<sf::String,VisibleGameObject*>::iterator。当它运行时:

return gameObjects.erase(results);

我期望VisibleGameObject的析构函数能够运行,即:

VisibleGameObject::~VisibleGameObject(){
    m_pSceneManager->removeSprite(name);
}

永远不会运行,直到保存gameObjects的类被销毁,然后运行:

GameObjectManager::~GameObjectManager(){
    std::for_each(gameObjects.begin(),gameObjects.end(),GameObjectDeallocator());
}

struct GameObjectDeallocator{
        void operator()(const std::pair<sf::String,VisibleGameObject*>&p) const{
            delete p.second;
        }
    };

然后它确实运行。为什么不在第一种情况下运行?

使用SFML 2.0

由于

2 个答案:

答案 0 :(得分:8)

erase会从容器中删除指针,但不会调用delete

建议:

  • 将您的地图更改为:

    std::map<sf::String,VisibleGameObject>
    

    即。对象不是它们的指针

或:

  • 使用shared_ptr / unique_ptr(例如boost::shared_ptrstd::shared_ptr,视具体情况而定):

    std::map<sf::String,std::shared_ptr<VisibleGameObject> >
    

    调用析构函数

答案 1 :(得分:0)

调用erase()不会释放指针,因为实现(map)不知道指向的对象是如何分配的(例如:它应该调用delete还是free?)更重要的是它不拥有指针即存储指针时不会将所有权转移到容器中。

使用std :: unique_ptr包装指针,然后按值将其存储在容器中。这将有助于垃圾收集,并为您提供所需。

using VisibileGameObjectPtr = std::unique_ptr<VisibleGameObject>; std::map<sf::String,VisibleGameObjectPtr> gameObjects;

// memory will be automatically garbage collected when you erase this item. gameObject["key"] = VisibileGameObjectPtr(new VisibleGameObject(..args..));