I have a lot of code where I am deleting vector containers that have pointers in them, that is, I have to delete all the pointers first and then clear the container. Every time I would iterate through and delete the pointers manually (I am aware of stl::algorithms for_each). To circumvent all that code, I created a template for deleting all vector containers that have a pointer. So far so good.
Now I have several more container types including maps, concurrent containers etc. all with the same functionality in the end as far as deletion goes. The DeleteContainer(std::vector<T*>& VecIn)
function that I have can only work on vectors as mentioned above. Is there any way to make it generic enough to work on all containers?
EDIT: Thanks for all the answers, I wish I could select more than one. To anybody who stumbles onto this question, read all the answers and not just the selected one as they all provide great info.
You already have a valid answer, but just to provide an alternative, I believe you should consider using Boost Pointer Container and let it handle memory management :
This library therefore provides standard-like containers that are for storing heap-allocated or cloned objects (or in case of a map, the mapped object must be a heap-allocated or cloned object). For each of the standard containers there is a pointer container equivalent that takes ownership of the objects in an exception safe manner.
You could use boost pointer containers.
They hold maintain and delete pointers correctly.
http://www.boost.org/doc/libs/1_38_0/libs/ptr_container/doc/reference.html
{
boost::ptr_vector<int> data;
data.push_back(new int(2));
data.push_back(new int(2));
data.push_back(new int(2));
}
// container deleted and all pointers correctly destroyed.
I'll second many people and avise using shared_ptr
or boost pointer containers. However, you can write
template <typename Iter>
void delete_pointers(Iter begin, Iter end)
{
for (; begin != end; ++begin) delete *begin;
}
Usage:
std::vector<Foo*> v;
// Initialize Foo objects
delete_pointers(v.rbegin(), v.rend());
I use rbegin
and rend
instead of begin
and end
because sometimes, people want objects to be deleted in the reverse order they were created.
You can also do
void destroyFoo(Foo* x) { delete x; }
std::for_each(v.rbegin(), v.rend(), &destroyFoo);
or use C++0x lambdas.
You can just use boost::shared_ptr<T>
insted of T*
and there will not be reason of DeleteContainer
. But If you don't want to do this, you can make something like this
template<class T>
void DeleteContainer(typename T::iterator begin, typename T::iterator end)
{
for(;begin!=end;++begin)
delete *begin;
}
then you can just call it for any stl container you want in this way:
std::some_container<int*> s;
DeleteContainer<std::some_container<int*> > (s.begin(), s.end());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With