映射迭代器擦除未调用适当的析构函数
map iterator erase not calling appropriate destructors
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
感谢
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> >
哪个将调用析构函数
调用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..));
- 析构函数调用
- 在具有向量的类构造函数中进行析构函数调用
- 从 c++ 中派生类的析构函数调用虚函数
- C++析构函数调用两次,堆栈分配的复合对象
- C++ 在析构函数调用之前删除的动态成员数组
- 析构函数调用c++中的一个向量
- Singleton模式中的手动析构函数调用:调用多次
- 从内部类的析构函数调用虚拟函数
- 与 boost odeint 集成期间的析构函数调用
- 堆栈展开如何与析构函数调用有关?
- C++:优化析构函数调用
- 以逗号分隔的表达式中的析构函数调用
- GCC 9.1 返回 void& 作为显式析构函数调用的结果类型。这是一个错误吗?
- 从C++中的虚拟析构函数调用虚拟方法
- 从指针返回对象时出现意外的析构函数调用
- 使用 decltype 显式析构函数调用
- C++析构函数调用了错误的对象
- 了解虚拟函数和析构函数调用
- 多重继承析构函数调用他自己和父析构函数?c++
- 析构函数调用表单不适当的库