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

C++ 这是删除和擦除向量中存储的对象指针的正确方法吗?,c++,stl,C++,Stl,我对STL不是很好,我看到很少有类似于我的要求的帖子,我感到困惑。所以,我需要一些关于以下代码的建议 SomeStruct someStruct(identifier); std::vector<SomeStruct*>::iterator it = std::find_if(vWrapper.begin(), vWrapper.end(), SomeStruct::Find_SomeStruct(&someStruct));

我对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);
        }
SomeStruct SomeStruct(标识符);
std::vector::iterator it=std::find_if(vWrapper.begin()、vWrapper.end()、SomeStruct::find_SomeStruct(&SomeStruct));
if(it!=vwraper.end())
{
...
删除*它;
它=vwraper.erase(它);
}
我试图根据标识符窥视向量,然后删除指向存储在向量中的对象的指针

我看到了那张照片。它利用for循环并重新分配迭代器。此外,没有一篇文章使用了find_if()then delete和erase


我这样做对吗?

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

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

但是你的代码和他们的代码之间的主要区别是,你的代码最多删除一个对象,他们的代码可以删除所有对象(使用functor的对象,在functor内部,它在满足条件时删除对象)

对于正确编写的
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 SomeStruct(标识符);
std::vector::iterator it=std::find_if
(
vwraper.begin(),
vwraper.end(),
SomeStruct::Find_SomeStruct(&identifier)
);
第一条线在那里干什么?你声明了一个变量却忘了?也许,你在别的地方用它;那样的话,没关系


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

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

所以不是

std::vector<SomeStruct*> vec;
std::向量向量向量机;
,使用

std::向量向量向量机;
那么,删除一个项目怎么样

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());
vec.erase(std::remove_if(vec.begin(),vec.end(),
[&vec](标准::共享项目)
{
bool condition=//该项反删除的条件,如item->x==0;
返回条件;
}
),vec.end());

从形式上讲,您所做的是未定义的行为,但实际上是 我说,很好。发生未定义的行为是因为
std::vector
要求其所有内容都可复制且 任何时候都是可赋值的,delete使指针的值保持不变 传递无效,因此不可计算。实际上:
std::vector
不是 要复制指针值,如果您在之后立即擦除它,我 不知道今天有哪台机器,删除的指针值真的不能 抄袭没有风险。(只是不要取消引用。)如果你真的 要避免未定义的行为,可以执行以下操作:

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

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

最好使用
shared\u ptr
,或者
unique\u ptr
(如果可以使用C++11),因为它们允许在所有操作中正确删除资源(例如,在复制向量后)。我通常建议。在
删除
后需要执行
擦除操作,它只将项移动到末尾并返回该迭代器。
remove\u如果
不会删除项(从而缩短向量),它只会将所有未删除的项合并在一起。对于包含它所拥有的(原始)指针的容器,决不能使用
remove
remove\u if
。@sad\n是的,但他最初的帖子使用了原始指针。(如果容器要拥有指向对象,那么
shared\u ptr
是最好的解决方案。但他的帖子中没有任何假设。)@JamesKanze:是的,我应该解释一下使用
std::shared\u ptr的目的。
实际上我编辑了我的帖子,而不是删除它。由于我的回答中其余的解释似乎是正确的,并且对OP有用(我希望)@Nawaz你的帖子没有问题。这是一个相当特殊的情况,其中(至少IMHO),未定义的行为确实相当迂腐。我认为你在实践中不会遇到任何问题,我自己也经常编写类似于他的代码。复制无效的指针值真的有用吗?您能给我指出标准的相关部分吗?@MatteoItalia§3.7.4.2/4:“如果标准库中的释放函数的参数是一个非空指针值的指针(4.10),解除分配函数将解除分配指针引用的存储,从而使引用解除分配存储的任何部分的所有指针无效。使用无效指针值(包括将其传递给解除分配函数)的效果未定义。“@7VIE包含无效值的变量的左值到右值转换未定义的原因行为是因为所有类型(字符和无符号字符除外)都可能具有补漏白表示。在指针的情况下,可以很容易地想象一个实现
SomeStruct* tmp = *it;
it = vWrapper.erase(it);
delete tmp;