循环矢量时自动删除对象

发布于 2024-12-01 23:55:30 字数 966 浏览 0 评论 0原文

我有一个对象的 std::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();
    }
}

I have an std::vector of objects and i cycle it calling some methods of the object. One of them will check a particular condition and if needed will delete itsef from the vector. The point is that erasing the element invalidate the iterator and I cannot continue the loop of it. I found boost::shared_ptr and boost::weak_ptr, could these fix the problem deleting the object after calling all methods and after incremented the iterator? If so, how?

EDIT 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();
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

与往事干杯 2024-12-08 23:55:30

不要介意你的向量包含什么——托管资源的删除确实可以留给智能指针,但更紧迫的问题是如何操作容器本身。

std::vector 确实具有非常差的迭代器失效:擦除或插入会使从擦除/插入开始的所有迭代器失效,因此您甚至不能使用标准 earase( it++) 习语。但你也不应该这样做,因为从向量中删除是昂贵的。更好的解决方案是使用删除/擦除并提供一个函子来检查擦除条件,然后一次性擦除所有内容:

std::vector<T> v;

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

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

如果你现有的算法太复杂,也许你可以在自己的算法中采用remove的思想,用swap将要擦除的对象移动到向量的后面>,并在算法结束时返回经过最后一个好元素的迭代器。然后,您可以在要删除的对象范围上拥有自己的可选清理循环,然后在该范围上调用erase

Never mind what your vector contains - the deletion of managed resources can indeed be left to smart pointers, but the more pressing issue is how to manipulate the container itself.

std::vector indeed has very poor iterator invalidation: erasing or inserting invalidates all iterators from the erasee/insertee onwards, so you cannot even use the standard earase(it++) idiom. But neither should you, since erasing from a vector is expensive. The better solution is to use remove/erase and supply a functor that checks the condition for erasure, and then erase everything in one wash:

std::vector<T> v;

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

Here MyPred is a predicate that implements your criterion. In C++11 this could be a handy lambda.

If your existing algorithm is too involved, perhaps you can adapt the idea of remove in your own algorithm and move the to-be-erased object to the back of the vector with swap, and return the iterator past the last good element at the end of the algorithm. Then you can have your own optional clean-up loop on the range of objects to be deleted, and then call erase on that range.

离去的眼神 2024-12-08 23:55:30

当您提到调用成员函数时,您应该使用 std erase/remove idiom ::mem_fun_ref

v.erase(std::remove_if(v.begin(), v.end(), std::mem_fun_ref(&Class::function), v.end()));

As you mention calling a member function you should the erase/remove idiom with std::mem_fun_ref

v.erase(std::remove_if(v.begin(), v.end(), std::mem_fun_ref(&Class::function), v.end()));
只是偏爱你 2024-12-08 23:55:30

要安全地从向量中删除元素,您应该使用erase-remove idiom< /a>.

编辑:在我之前发布了很多好的回复,所以我想对remove添加一些额外的说明,因为它的运作方式并不是很明显。 remove 算法实际上不会删除任何东西。它所做的只是对容器进行洗牌,以便所有要保留的元素都位于容器的开头。然后,它返回一个迭代器到保留元素的末尾(最后一个要保留的元素之后),此时您可以使用erase来实际缩短容器。例如:

向量 v;...
v.erase(remove(v.begin(), v.end(), 99), v.end());

将删除 v 中的所有元素值99。

To safely delete elements from a vector you should use the erase-remove idiom.

EDIT: Lots of good responses posted before mine, so thought I'd add a little extra clarification on remove because it's not immediately obvious how it operates. The remove algorithm doesn't actually remove anything. All it does is shuffle the container such that all the elements to keep are at the beginning of the container. It then returns an iterator to the end of the kept elements (one past the last element to keep) and that's when you use erase to actually shorten the container. For example:

vector v;...
v.erase(remove(v.begin(), v.end(), 99), v.end());

will remove all elements in v with the value 99.

吻泪 2024-12-08 23:55:30

使用擦除-删除习惯用法:

// You can write a function, a functor or use lambda directly it is up to you!
bool condition(const vector<object>& v);
v.erase( remove_if(v.begin(), v.end(), condition), v.end() );

这是一篇精彩的文章,讨论了编写涉及迭代器的算法的主题

Use the erase-remove idiom:

// You can write a function, a functor or use lambda directly it is up to you!
bool condition(const vector<object>& v);
v.erase( remove_if(v.begin(), v.end(), condition), v.end() );

This is a fantastic article talking about the subject of writing algorithms involving iterators.

数理化全能战士 2024-12-08 23:55:30

您可以从erase() 返回一个有效的迭代器。

for(... it = vec.begin(); it != vec.end(); it++) {
    if (condition(it))
        it = --vec.erase(it);
}

当然,您应该始终使用智能指针来管理资源。

You can get a valid iterator back from erase().

for(... it = vec.begin(); it != vec.end(); it++) {
    if (condition(it))
        it = --vec.erase(it);
}

Of course, you should always use smart pointers to manage resources.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文