清理STL列表/指针向量

twk*_*twk 49 c++ stl

为了安全地清理向量或指针列表,你可以用最短的C++块来实现什么?(假设您必须在指针上调用delete?)

list<Foo*> foo_list;
Run Code Online (Sandbox Code Playgroud)

我宁愿不使用Boost或用智能指针包装我的指针.

Joh*_*itb 55

对于std::list<T*>使用:

while(!foo.empty()) delete foo.front(), foo.pop_front();
Run Code Online (Sandbox Code Playgroud)

对于std::vector<T*>使用:

while(!bar.empty()) delete bar.back(), bar.pop_back();
Run Code Online (Sandbox Code Playgroud)

不知道为什么我采取front而不是back为了std::list上面.我想这是感觉它更快.但实际上两者都是恒定时间:).无论如何将它包装成一个函数并享受乐趣:

template<typename Container>
void delete_them(Container& c) { while(!c.empty()) delete c.back(), c.pop_back(); }
Run Code Online (Sandbox Code Playgroud)

  • @EternalLearner调用析构函数不会取消分配内存.您仍然需要在指针上调用`delete`以便取消分配内存. (6认同)
  • 我建议不要使用逗号(序列)运算符.太多的C++开发人员不知道它做了什么,并将其误认为是分号. (5认同)
  • 技术上是正确的,但如果你使用更常见的大括号和缩进约定,它会变得更长. (2认同)
  • @Johannes Schaub - 有必要调用delete.不是在调用pop_back()吗?当我读到pop_back的内容时,我看到它也调用了被删除的元素析构函数. - http://www.cplusplus.com/reference/stl/vector/pop_back/. (2认同)

Mr.*_*Ree 51

因为我们在这里抛弃了挑战......"C++中最短的一块"

static bool deleteAll( Foo * theElement ) { delete theElement; return true; }

foo_list . remove_if ( deleteAll );
Run Code Online (Sandbox Code Playgroud)

我认为我们可以相信那些提出STL的人可以拥有高效的算法.为什么重新发明轮子?

  • 当Predicate有副作用时,它只是我还是觉得真的错了? (29认同)

Dou*_*der 31

for(list<Foo*>::const_iterator it = foo_list.begin(); it != foo_list.end(); ++it)
{
    delete *it;
} 
foo_list.clear();
Run Code Online (Sandbox Code Playgroud)


Adi*_*sak 16

如果你允许C++ 11,你可以做一个非常简短的Douglas Leeder的答案:

for(auto &it:foo_list) delete it; foo_list.clear();
Run Code Online (Sandbox Code Playgroud)


Mar*_*som 13

依靠容器外部的代码删除指针真的很危险.例如,当容器因抛出异常而被销毁时会发生什么?

我知道你说你不喜欢提升,但请考虑提升指针容器.


Joh*_*ing 9

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>());
Run Code Online (Sandbox Code Playgroud)


CB *_*ley 6

我不确定这里的functor方法是否简洁.

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

不过,我通常会建议不要这样做.通常,将指针包装在智能指针中或使用专业指针容器会变得更加健壮.有很多方法可以从列表中删除项目(各种风格的erase,clear列表的破坏,通过迭代器分配到列表中等).你能保证能抓住他们吗?


Lin*_*umz 5

当您的列表使用RAII超出范围或者调用list :: clear()时,以下hack会删除指针.

template <typename T>
class Deleter {
public:
  Deleter(T* pointer) : pointer_(pointer) { }
  Deleter(const Deleter& deleter) {
    Deleter* d = const_cast<Deleter*>(&deleter);
    pointer_ = d->pointer_;
    d->pointer_ = 0;
  }
  ~Deleter() { delete pointer_; }
  T* pointer_;
};
Run Code Online (Sandbox Code Playgroud)

例:

std::list<Deleter<Foo> > foo_list;
foo_list.push_back(new Foo());
foo_list.clear();
Run Code Online (Sandbox Code Playgroud)