映射迭代器擦除未调用适当的析构函数

map iterator erase not calling appropriate destructors

本文关键字:析构函数 调用 迭代器 擦除 映射      更新时间:2023-10-16

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

感谢

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

建议:

  • 将您的地图更改为:

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

    即对象不是指向它们的

或:

  • 使用shared_ptr/unique_ptr(例如boost::shared_ptrstd::shared_ptr,取决于可用性):

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

    哪个调用析构函数

调用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..));