为了安全地清理向量或指针列表,你可以用最短的C++块来实现什么?(假设您必须在指针上调用delete?)
listfoo_list;
我宁愿不使用Boost或用智能指针包装我的指针.
对于std::list
使用:
while(!foo.empty()) delete foo.front(), foo.pop_front();
对于std::vector
使用:
while(!bar.empty()) delete bar.back(), bar.pop_back();
不知道为什么我采取front
而不是back
为了std::list
上面.我想这是感觉它更快.但实际上两者都是恒定时间:).无论如何将它包装成一个函数并享受乐趣:
templatevoid delete_them(Container& c) { while(!c.empty()) delete c.back(), c.pop_back(); }
因为我们在这里抛弃了挑战......"C++中最短的一块"
static bool deleteAll( Foo * theElement ) { delete theElement; return true; } foo_list . remove_if ( deleteAll );
我认为我们可以相信那些提出STL的人可以拥有高效的算法.为什么重新发明轮子?
for(list::const_iterator it = foo_list.begin(); it != foo_list.end(); ++it) { delete *it; } foo_list.clear();
如果你允许C++ 11,你可以做一个非常简短的Douglas Leeder的答案:
for(auto &it:foo_list) delete it; foo_list.clear();
依靠容器外部的代码删除指针真的很危险.例如,当容器因抛出异常而被销毁时会发生什么?
我知道你说你不喜欢提升,但请考虑提升指针容器.
template< typename T > struct delete_ptr : public std::unary_function{ bool operator()(T*pT) const { delete pT; return true; } }; std::for_each(foo_list.begin(), foo_list.end(), delete_ptr ());
我不确定这里的functor方法是否简洁.
for( list::iterator i = foo_list.begin(); i != foo_list.end(); ++i ) delete *i;
不过,我通常会建议不要这样做.通常,将指针包装在智能指针中或使用专业指针容器会变得更加健壮.有很多方法可以从列表中删除项目(各种风格的erase
,clear
列表的破坏,通过迭代器分配到列表中等).你能保证能抓住他们吗?
当您的列表使用RAII超出范围或者调用list :: clear()时,以下hack会删除指针.
templateclass Deleter { public: Deleter(T* pointer) : pointer_(pointer) { } Deleter(const Deleter& deleter) { Deleter* d = const_cast (&deleter); pointer_ = d->pointer_; d->pointer_ = 0; } ~Deleter() { delete pointer_; } T* pointer_; };
例:
std::list> foo_list; foo_list.push_back(new Foo()); foo_list.clear();