5

我们应该删除之前还是之后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???
}
4

5 回答 5

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();
于 2010-09-17T06:51:01.010 回答
4

使用迭代器擦除元素会使迭代器无效。您应该在删除该项目之前将其删除。

您还应该使用擦除的返回值进行下一次循环迭代。

于 2010-09-17T06:28:27.857 回答
3

此外,是否有任何情况下我们不想在删除元素时删除它?

向量怎么可能知道其他人是否需要指向的对象?它怎么会知道指针存储在堆上呢?完全有可能在向量中有指向静态或自动对象的指针,甚至是悬空指针。

C++0x 允许你表达向量应该拥有指针:

std::vector<std::unique_ptr<foo>> vec;

现在您不必手动删除任何内容。通过擦除唯一指针,它们各自的指针也被删除。本机指针的容器在现代 C++ 中非常少见。

如果你没有 C++0x 编译器,你可以使用std::vector<boost::shared_ptr<foo> >orboost::ptr_vector<foo>代替。现代编译器也会shared_ptrstd::tr1orstd命名空间中提供#include <memory>.

于 2010-09-17T08:42:18.853 回答
2

擦除第一个元素会导致整个数组向前移动的向量的性质,要减少此操作,请尝试以下操作:

std::vector<foo*> v1;
//...
while(!v1.empty())
{
    delete v1.back();
    v1.pop_back( );
}

顺便说一句 - 此方法不会使任何迭代器无效(仅在已删除的项目上)

于 2010-09-17T07:07:07.933 回答
1

执行 anerase将使vector迭代器无效。因此*iter将调用未定义的行为。因此,您需要deleteerase. 此外,您不能erase在一段时间内迭代它的元素vector(由于相同的原因,iter变得无效所以iter++无效)。在这种情况下,您可以erase从循环内部删除调用并在循环clear外部执行向量。

于 2010-09-17T06:33:49.797 回答