2012-02-25 6 views
1

gameObjects - std::map<sf::String,VisibleGameObject*>, а results - std::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

Благодарность

+5

Почему вы ожидаете деструктор 'VisibleGameObject' работать, когда вы уничтожить' VisibleGameObject * '? Нет 'VisibleGameObject' уничтожается, только указатель. –

+1

Не используйте голые указатели в C++. Шутки в сторону. Их трудно понять, утомляя рассуждения и почти всегда причиной чьего-то недоразумения. –

+0

Потому что я тупой! Я так много раз совершал ошибки, я должен учиться! – pighead10

ответ

7

erase удаляет указатели из контейнера, но не вызова delete.

Предложение:

  • изменить вашу карту, чтобы быть просто:

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

    т.е. объекты не указатели на них

или:

  • использовать shared_ptr/unique_ptr (например, boost::shared_ptr или std::shared_ptr в зависимости от наличия):

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

    который будет вызов деструктора

0

вызова стирания() не освобождает указатель в качестве реализации (карта) не знает, как указанный объект был выделен ((например: следует ли его удалить или освободить?) и, что более важно, он не владеет указателем, т.е. вы не передаете право собственности на контейнер при хранении указателей.

Используйте 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..));

 Смежные вопросы

  • Нет связанных вопросов^_^