1

std::listそのリストを繰り返し処理しているときに、内のオブジェクトの位置を移動したり、リストから削除したりする必要がある状況をどのように管理しますか?

複雑な例を次に示します。

オブジェクトの順序 listがあります。

list< Object* > objects ;

それぞれを繰り返すループがあります

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

これがキャッチです。 は、上記のループで反復処理を行っているまさにリストであるlistObject::move()の順序を変更することがあります。

これを設計する方法がわかりません。リストを呼び出すたびにリストの順序を変更し、リスト内の各要素を反復処理して各要素を呼び出すメンバー関数を作成して呼び出すにはどうすればObject::move()よいですかobjectsObject::move()Objectlist

4

2 に答える 2

3

全体的に。

コンテナーを認識して操作するコンテナー オブジェクトにメンバーを配置することは、ほとんどの場合、設計上の選択として不適切です。コンテナ->含まれているが含まれていない->コンテナが必要です。

あなたのソートルーチンはまさにそれである必要があります。「移動」がそうでなければ、いつ物事を交換するかを決定するために使用するルールを使用するソートルーチンです。基本的に、すべての要素に対して「move」を呼び出すと、何らかの条件でリストを順序付けているため、順序付けが必要な方法を知っている何かによって移動されるように、要素自体が移動するというこの考えを変更するだけです。もちろん、これを行う場合、その条件はクライアントのニーズごとに異なる場合があります。

于 2012-12-09T21:35:36.773 に答える
0

に電話する前に、次の人が誰であるかを覚え おく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 ;
}

このループを に呼び出す前に、moved各内部にフラグを設定できます。 が呼び出されると、そのフラグは true に切り替わります。そうすれば、オブジェクトがリストの前に移動された場合 (それは問題ではありません)、オブジェクトがリストの最後に移動された場合でも、2 回要求されることはありません。また、これにより、すべてのオブジェクトが少なくとも 1 回移動するように求められ、リストのはるか下に移動して多くの要素をスキップするためにオブジェクトがスキップされるシナリオがなくなります。objectfalseObject::move::moveiter++iter

于 2012-12-09T21:38:39.237 に答える