这是删除和删除存储在向量中的对象的指针的正确方法吗?

时间:2011-12-07 11:27:28

标签: c++ stl

我对STL不是很好,我看到很少的帖子与我的要求类似,并且感到困惑。因此,我需要对以下代码提出一些建议。

        SomeStruct someStruct(identifier);
        std::vector<SomeStruct*>::iterator it = std::find_if(vWrapper.begin(), vWrapper.end(), SomeStruct::Find_SomeStruct(&someStruct));
        if(it != vWrapper.end()) 
        {
            ...
            delete *it;  
            it = vWrapper.erase(it);
        }

我试图根据标识符查看向量,然后删除指向存储在向量中的对象的指针。

我看到了post。它使用for循环并重新分配迭代器。此外,没有帖子使用find_if()然后删除和擦除。

我是以正确的方式做到的吗?

3 个答案:

答案 0 :(得分:6)

正式地说,你所做的是未定义的行为,但实际上 说,没关系。发生未定义的行为是因为 std::vector要求其所有内容都是可复制的 可分配,始终和删除使得它的指针值 通过无效,因此不可行。在实践中:std::vector不是 如果你之后立即删除指针值,我将复制指针值 不知道今天的机器哪里删除指针值不能真正 被复制没有风险。 (只是不要取消引用它。)如果你真的 想要避免未定义的行为,你可以做类似的事情:

SomeStruct* tmp = *it;
it = vWrapper.erase(it);
delete tmp;

但坦率地说,我不确定这是值得的。

答案 1 :(得分:3)

调用未定义的行为。有关解释,请阅读@James Kanze的answer

我宁愿转到下一个问题:如果在其他主题中,答案都没有使用过std::find_if,那么这是因为这些帖子没有谈到删除和删除特定的元素。他们 似乎删除了所有元素,或者很少有人使用仿函数来检查要删除的对象,这也没关系。

但是代码和代码之间的主要区别在于您的代码最多删除并删除了 一个对象,并且他们的代码可以删除所有对象(使用仿函数的对象,在仿函数中删除符合条件的对象)。

对于正确编写的std::find_if,这就是我所能说的。

然而,实际上,我无法理解您的代码,尤其是这两行:

//I formatted the code so that entire code is visible without 
//scrolling horizontally

SomeStruct someStruct(identifier); 
std::vector<SomeStruct*>::iterator it = std::find_if
                                   (
                                     vWrapper.begin(), 
                                     vWrapper.end(),
                                     SomeStruct::Find_SomeStruct(&identifier)
                                   );

那里的第一线是什么?你声明了一个变量并忘了它?好吧,也许,你在其他地方使用它;在那种情况下,没关系。

但是SomeStruct::Find_SomeStruct是什么?它是一个嵌套类,可以像仿函数一样工作吗?静态功能还是什么?你的编译成功吗?完整的答案也取决于我提出的这些问题。

答案 2 :(得分:1)

就个人而言,我没有容器中的原始指针,也没有处理你问的问题。我不认为选择正确的方法来删除它们。使用智能指针,比如std :: shared_ptr,当智能指针超出范围RAII时,它将删除它拥有的原始指针。

所以而不是

std::vector<SomeStruct*> vec;

,使用

std::vector<std::shared_ptr<SomeStruct>> vec;

那么删除一个项目呢?

vec.erase(std::remove_if( vec.begin(), vec.end(), 
  [&vec]( std::shared_ptr<SomeStruct> & item ) 
  {
    bool condition = // The condition on which the item will de deleted. e.g. item->x == 0;
    return condition;
  }
),vec.end());