拥有一个拥有 原始指针的STL容器(例如std::vector)通常是个坏主意。这可能是 leaktrocity 的来源:例如如果在某处抛出异常,则调用向量析构函数,但这将不会删除原始拥有的指针!所以他们的相关资源被泄露了。
此外,您必须提供明确的清理代码等。
您可能想要使用std::vector<Object> 或智能指针 的std::vector,例如vector<shared_ptr<Object>> 或 vector<unique_ptr<Object>>(由于移动语义,后者从 C++11 开始可用,如果 vector 是对象的 唯一 所有者,并且没有共享所有权)。
您可能还想使用 算法,例如 remove_if()。特别是,要从 vector 中删除满足某些精确条件的项目,您可能需要使用所谓的 erase-remove idiom:
// Use a vector of *smart pointers* (shared_ptr or unique_ptr).
typedef std::shared_ptr<Object> ObjectPtr;
std::vector<ObjectPtr> v;
...
...
// Use the erase-remove idiom to erase items satisfying a particular condition.
v.erase( std::remove_if(v.begin(), v.end(), [&](const ObjectPtr & p) {
return p->m_id == deleteId; // Erasing condition
}), v.end());
为了使代码更清晰(特别是如果你不知道/识别擦除删除习语),可以编写一个小辅助函数来实现这个习语:
// Helper function to implement the erase-remove idiom for std::vector.
template <typename T, typename Predicate>
void erase_if(std::vector<T>& v, Predicate p) {
v.erase(std::remove_if(v.begin(), v.end(), p), v.end());
}
然后这样称呼它:
// Simplified code: just pass the vector 'v' and the erasing condition
// (in this case using a simple lambda).
// Uses the erase-remove idiom under the hood.
//
erase_if(v, [&](const ObjectPtr & p) { return p->m_id == deleteId; });
请注意,由于使用了remove_if 算法 和擦除删除习语,您的代码的语义级别 提高了:您没有阅读显式 for 循环和迭代器不再递增;您只需阅读清楚的代码intent,即擦除满足给定条件的项目。
PS:您可能还想阅读:"How do I erase elements from STL containers?"。