我有一个对象的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/