Delete any container using templates

自闭症网瘾萝莉.ら 提交于 2019-12-22 04:07:36

问题


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.


回答1:


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.




回答2:


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.



回答3:


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.




回答4:


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());



回答5:


As suggested by Tomek, we can have a similar solution to handle the deletion. A struct would have been better than a free function.

struct Delete
{
   public:
      template<typename T>
      void operator()(const T* ptr) const
      {
          delete ptr;
      }
      void operator()(const char* ptr) const
      {
          delete[] ptr;

     }
};

for_each(some_container.begin(), some_container.end(), Delete());




回答6:


An alternative is to give up on deleting things entirely and commit to using a garbage collector :) You can try the Boehm-Reiser-Detlefs collector, it is standard on Linux (libgc) and it is used in many complex programs now (such as gcc). It's also a good idea to give up on RAII: it was a nice idea at the time but it doesn't work so well in practice. Many resources are independently created and destroyed out of order with their representation.




回答7:


My take on this would be:

template<class T>
void Destroy(T *p)
{
  delete p;
}

template<template<typename, typename> class C, typename T1, typename T2>
void Destroy(C<T1 *, T2> &c)
{                                                        
  std::for_each(c.begin(), c.end(), Destroy<T1>);
}

Tested on g++ 4.4.4 with vector, deque and list. You may need additional overloads of void Destroy(C<T1 *, T2> &c) for other containers and/or other STL implementations.



来源:https://stackoverflow.com/questions/4479381/delete-any-container-using-templates

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!