0

順序はどちらの方法でもかまいません (最初に消去してからプッシュバックします。この方法では、オブジェクトへのローカル参照を作成する必要がないということだけです)。

  for ( GameObjItr gameObj = m_gameObjects.begin();
        gameObj != m_gameObjects.end(); gameObj++ ) {
    if ( *gameObj && *gameObj != gameObject ) {
      const sf::FloatRect &otherObj = ( *gameObj )->GetCollisionBox();
      if( mainObj.Intersects( otherObj ) ) {
        m_gameObjects.splice( m_gameObjects.end(), m_gameObjects, gameObj );
        return m_gameObjects.back();
      }
    }
  }

  return NULL;
}

関数が渡されたオブジェクトと衝突するオブジェクトを見つけた場合、そのオブジェクトをリストの最後に追加し、現在の位置から削除してからオブジェクトを返すという考え方です。消去後すぐに戻るので、イテレータの無効化は問題ではないと思いますか?

このコードにより、プログラムがクラッシュします。

PS cppreference は、消去はオブジェクトを「削除」すると言っていますが、これは単にリストから削除しただけだと思いました。(これが間違っている場合、その場所で要素を削除するにはどうすればよいですか。私が読んでいる削除関数ドキュメントでは、オブジェクトの値を渡すことしかできません)。

編集: クラッシュの場所は常に同じではありませんが、このコードが原因で発生します (つまり、元に戻すと正常に動作します)。可変時間遅延クラッシュの原因は何ですか? 見つかったオブジェクトを破棄したくありません。

GameObject* GameObjectManager::DetectCollision( const GameObject *
  gameObject ) {
  const sf::FloatRect &mainObj = gameObject->GetCollisionBox();

  for ( GameObjItr gameObj = m_gameObjects.begin();
        gameObj != m_gameObjects.end(); gameObj++ ) {
    if ( *gameObj && *gameObj != gameObject ) {
      const sf::FloatRect &otherObj = ( *gameObj )->GetCollisionBox();
      if( mainObj.Intersects( otherObj ) ) {
        m_gameObjects.splice( m_gameObjects.end(), m_gameObjects, gameObj ); //<--------
        return m_gameObjects.back(); //<-------------
      }
    }
  }

  return NULL;
}

編集 オブジェクトをリストの最後に移動すると、衝突する 2 つのゲームオブジェクト間で無限ループが発生するというバグが見つかりました。申し訳ありませんが、投稿されたコードから解読できませんでした。

4

2 に答える 2

0

"m_gameObjects.splice(m_gameObjects.end()、m_gameObjects、gameObj);"
gameObjをリストの最後の位置に移動しますか?それが上の行が示唆していることです。はいの
場合、gameObj == m_gameObjects.end()または++ gameObj == m_gameObjects.end()の
場合、これはNULL操作です。

もう1つ、forループのイテレータでポストインクリメントを実行して、それをプレインクリメントにします。ただし、これはクラッシュとは関係ありません。

于 2010-07-12T22:52:42.973 に答える
0

あなたが言う時:

m_gameObjects.erase( gameObj );

消去されるリストに含まれるもののデストラクタ (存在する場合) が呼び出されます。あなたの質問から、このもののタイプが何であるか、またはこのデストラクタの呼び出しが予想されるかどうかは明らかではありません。

于 2010-07-12T22:30:39.797 に答える