对列表中的每个对象调用成员函数,以改变对象所在的列表

Invoking a member function on each object in a list that mutates the list the objects are in

本文关键字:对象 列表 函数 改变 调用 成员      更新时间:2023-10-16

当您迭代该列表时,您如何管理std::list中的对象需要将其位置移入甚至从该列表中删除的情况?

下面是一个复杂的例子。

您有一个有序list的对象。

list< Object* > objects ;

你有一个循环来迭代每个

for( list< Object* >::iterator iter = objects.begin() ; iter != objects.end() ; ++iter )
{
    // call "move()" on each
    (*iter)->move() ;
}

现在这就是问题所在。 Object::move()有时会对列表重新排序,即我们使用上面的循环迭代的列表。

我不知道如何设计这个。 如何编写和调用成员函数Object::move(),该函数可能在每次调用列表时对列表重新排序,并迭代objects列表中的每个元素,在list中的每个Object上调用Object::move()

整体上。

将一个知道并操作容器的成员放在包含的对象中几乎普遍是一个糟糕的设计选择。 您需要容器>包含,但不包含>容器。

你的排序例程必须

就是这样,一个排序例程,它使用"移动"的任何规则来决定何时交换东西。 当你对所有元素调用"move"时,你基本上是按某种条件对列表进行排序,所以你只是改变了元素移动自己的想法,它们被知道它们需要如何排序的东西移动。 当然,当您这样做时,对于不同的客户需求,条件可能会有所不同。

我想

我可以记住下一个应该是谁,在打电话之前move(),并始终使用它。

for( list< Object* >::iterator iter = objects.begin() ; iter != objects.end() ; )
{
    // call "move()" on each
    list< Object* >::iterator shouldBeNext = iter ;
    ++shouldBeNext ;
    (*iter)->move() ;
    iter = shouldBeNext ;
}

我可以在每个object中设置一个moved标志,然后再调用这个循环来false,当调用Object::move时,该标志将切换到true。 这样,如果对象在列表中移动到前面(没关系),并且如果对象在列表中移动到较晚的位置,则不会要求它::move两次。 此外,这可确保要求每个对象至少移动一次,并消除了由于iter在列表中向下移动而跳过对象的情况,从而++iter跳过许多元素。