我们应该在erase
之前还是之后删除。我的理解都是好的。这是对的吗?
此外,是否有任何情况我们不想在删除元素时删除它?我相信必须有,否则,erase
将很乐意承担责任。
std::vector<foo*> bar;
...
for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); itr++)
{
delete (*itr); //before OR
bar.erase(itr);
delete (*itr); //after???
}
答案 0 :(得分:10)
“itr”必须像这样使用;
for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); )
{
delete (*itr);
itr = bar.erase(itr);
}
但是,我宁愿先删除所有元素,然后清除矢量;
for (vector<foo*>::iterator itr = bar.begin(); itr != bar.end(); ++itr)
delete (*itr);
bar.clear();
答案 1 :(得分:4)
使用迭代器擦除元素会使迭代器无效。您应该在删除之前删除该项目。
您还应该使用擦除的返回值进行下一次循环迭代。
答案 2 :(得分:3)
此外,有没有我们不想在删除时删除元素?
矢量怎么可能知道是否还有其他人需要指向的对象?怎么可能知道这些蚂蚁存放在堆上?完全有可能在向量中指向静态或自动对象,甚至悬挂指针。
C ++ 0x允许您表示该向量应该拥有该对象:
std::vector<std::unique_ptr<foo>> vec;
现在您不必手动删除任何内容。通过擦除唯一指针,它们各自的指针也被删除。在现代C ++中,本机指针的容器非常罕见。
如果您没有C ++ 0x编译器,则可以使用std::vector<boost::shared_ptr<foo> >
或boost::ptr_vector<foo>
代替。如果您shared_ptr
,现代编译器也会在std::tr1
或std
命名空间中提供#include <memory>
。
答案 3 :(得分:2)
擦除第一个元素的向量的性质导致整个数组向前移动,以减少此操作尝试以下:
std::vector<foo*> v1;
//...
while(!v1.empty())
{
delete v1.back();
v1.pop_back( );
}
顺便说一下 - 这个方法不会使任何迭代器失效(仅在擦除的项目上)
答案 4 :(得分:1)
执行erase
将使vector
迭代器无效。所以*iter
将调用未定义的行为。因此,您需要在delete
之后执行erase
。另外,在erase
进行迭代时,您无法vector
iter
中的元素(由于相同的原因,iter++
变为无效,因此erase
无效)。在这种情况下,您可以从循环内部移除clear
调用,并在循环外执行向量的{{1}}。