Having an STL container (e.g. std::vector
) of owning raw pointers is in general a bad idea. This can be a source of leaktrocity: e.g. if an exception is thrown somewhere, the vector destructor is called, but that will not delete the raw owning pointers! So their associated resources are leaked.
Moreover you have to provide explicit cleanup code, etc.
You may want to either use std::vector<Object>
, or a std::vector
of smart pointers, e.g. vector<shared_ptr<Object>>
or vector<unique_ptr<Object>>
(the latter available since C++11 thanks to move semantics, and a good solution if the vector
is the unique owner of the objects, and there is no shared ownership).
You may also want to use algorithms like remove_if()
. In particular, to remove items satisfying some precise condition from vector
, you may want to use the so called 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());
The make the code clearer (especially if one doesn't know/recognize the erase-remove idiom), it's possible to write a little helper function to implement this idiom:
// 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());
}
And then call it like this:
// 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; });
Note that thanks to the use of the remove_if
algorithm and the erase-remove idiom, the semantic level of your code is raised: you don't read explicit for
loops and iterator incrementing anymore; you can just read the clear intent of the code, i.e. erasing items that satisfy a given condition.
PS: You might also want to read: "How do I erase elements from STL containers?".