我有一个对象的 std::vector,我循环它调用对象的一些方法。其中之一将检查特定条件,如果需要,将从 vector 中删除 itsef。关键是删除元素会使迭代器无效,我无法继续它的循环。我找到了 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
确实有非常差的迭代器失效:删除或插入会使 所有 从 erasee/insertee 开始的迭代器失效,所以你甚至不能使用标准的 earase(it++)
成语。但你也不应该,因为从 vector 中删除是昂贵的。更好的解决方案是使用 remove/erase 并提供一个仿函数来检查删除条件,然后一次性删除所有内容:
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/