Cleaning up an STL list/vector of pointers

后端 未结 15 1294
没有蜡笔的小新
没有蜡笔的小新 2020-11-28 21:41

What is the shortest chunk of C++ you can come up with to safely clean up a std::vector or std::list of pointers? (assuming you have to call delet

相关标签:
15条回答
  • 2020-11-28 22:18

    At least for a list, iterating and deleting, then calling clear at the end is a bit inneficient since it involves traversing the list twice, when you really only have to do it once. Here is a little better way:

    for (list<Foo*>::iterator i = foo_list.begin(), e = foo_list.end(); i != e; )
    {
        list<Foo*>::iterator tmp(i++);
        delete *tmp;
        foo_list.erase(tmp);
    }
    

    That said, your compiler may be smart enough to loop combine the two anyways, depending on how list::clear is implemented.

    0 讨论(0)
  • 2020-11-28 22:19
    for(list<Foo*>::const_iterator it = foo_list.begin(); it != foo_list.end(); ++it)
    {
        delete *it;
    } 
    foo_list.clear();
    
    0 讨论(0)
  • 2020-11-28 22:25

    For std::list<T*> use:

    while(!foo.empty()) delete foo.front(), foo.pop_front();
    

    For std::vector<T*> use:

    while(!bar.empty()) delete bar.back(), bar.pop_back();
    

    Not sure why i took front instead of back for std::list above. I guess it's the feeling that it's faster. But actually both are constant time :). Anyway wrap it into a function and have fun:

    template<typename Container>
    void delete_them(Container& c) { while(!c.empty()) delete c.back(), c.pop_back(); }
    
    0 讨论(0)
  • 2020-11-28 22:27

    I'm not sure that the functor approach wins for brevity here.

    for( list<Foo*>::iterator i = foo_list.begin(); i != foo_list.end(); ++i )
        delete *i;
    

    I'd usually advise against this, though. Wrapping the pointers in smart pointers or using a specialist pointer container is, in general, going to be more robust. There are lots of ways that items can be removed from a list ( various flavours of erase, clear, destruction of the list, assignment via an iterator into the list, etc. ). Can you guarantee to catch them all?

    0 讨论(0)
  • 2020-11-28 22:28
    template< typename T >
    struct delete_ptr : public std::unary_function<T,bool>
    {
       bool operator()(T*pT) const { delete pT; return true; }
    };
    
    std::for_each(foo_list.begin(), foo_list.end(), delete_ptr<Foo>());
    
    0 讨论(0)
  • 2020-11-28 22:29

    Since C++11:

    std::vector<Type*> v;
    ...
    std::for_each(v.begin(), v.end(), std::default_delete<Type>());
    

    Or, if you are writing templated code and want to avoid specifying a concrete type:

    std::for_each(v.begin(), v.end(),
        std::default_delete<std::remove_pointer<decltype(v)::value_type>::type>());
    

    Which (since C++14) can be shortened as:

    std::for_each(v.begin(), v.end(),
        std::default_delete<std::remove_pointer_t<decltype(v)::value_type>>());
    
    0 讨论(0)
提交回复
热议问题