順序はどちらの方法でもかまいません (最初に消去してからプッシュバックします。この方法では、オブジェクトへのローカル参照を作成する必要がないということだけです)。
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 つのゲームオブジェクト間で無限ループが発生するというバグが見つかりました。申し訳ありませんが、投稿されたコードから解読できませんでした。