我有一个对象的std::vector,我循环调用对象的某些方法。其中之一将检查特定条件,如果需要,将其从 vector 中删除。关键是擦除该元素会使迭代器无效,而我无法继续其循环。我发现boost::shared_ptr和boost::weak_ptr,这些可以解决在调用所有方法并增加迭代器之后删除对象的问题吗?如果是这样,怎么办?

编辑1

class CPippo
{
public:
     void Pippo();
     void Pippo2();
}

class CPippoManager
{
public:
    void PipppManager();
    void RemovePippo(CPippo *pippo);

private:
    std::vector<CPippo*> pippoVector;
}

void CPippo::Pippo()
{
    ...

    if (condition)
    {
        pippoManager->RemovePippo(this);
    }
}

void CPippo::Pippo2()
{
    ...
}

void CPippoManager::RemovePippo(CPippo *pippo)
{
    this->pippoVector.erase(this->pippoVector.begin(), this->pippoVector.end(), pippo);
}

void CPippoManager::PipppManager()
{
    for (std::vector<CPippo*>::iterator it = this->pippoVector.begin(); it != this->pippoVector.end; ++it)
    {
        (*it)->Pippo();

        (*it)->Pippo2();
    }
}

最佳答案

没关系, vector 包含什么-确实可以将托管资源的删除留给智能指针,但是更紧迫的问题是如何操作容器本身。
std::vector确实具有非常差的迭代器无效性:从擦除/插入开始,擦除或插入会使所有迭代器无效,因此您甚至不能使用标准earase(it++)惯用语。但是您也不应该,因为从 vector 中擦除很昂贵。更好的解决方案是使用删除/擦除功能,并提供一个函子来检查擦除条件,然后在一次清洗中擦除所有内容:

std::vector<T> v;

v.erase(std::remove_if(v.begin(), v.end(), MyPred), v.end());

这里MyPred是实现您的条件的谓词。在C++ 11中,这可能是一个方便的lambda。

如果您现有的算法过于复杂,也许您可​​以在自己的算法中适应remove的想法,并使用swap将要擦除的对象移到 vector 的后面,然后将迭代器返回到最后一个最后一个好元素之后算法的然后,您可以对要删除的对象范围进行自己的可选清理循环,然后在该范围内调用erase

关于c++ - 循环 vector 时自动删除对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7224820/

10-11 22:38
查看更多