Отталкивание объекта назад, затем стирание его в прежнем месте в std :: list - PullRequest
0 голосов
/ 13 июля 2010

Обратите внимание, что порядок может идти в любом направлении (сначала стереть, а затем отодвинуть назад, просто для того, чтобы этот путь не требовал создания локальной ссылки на объект).

  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;
}

Edit Обнаружена ошибка, при перемещении объекта в конец списка возникла бесконечная петля между двумя GameObjects, сталкивающимися.Извините, не удалось расшифровать отправленный код.

Ответы [ 2 ]

0 голосов
/ 13 июля 2010

"m_gameObjects.splice (m_gameObjects.end (), m_gameObjects, gameObj);"
Хотите переместить gameObj на последнюю позицию в списке?Это то, что предлагает приведенная выше строка.Если да, то
, если gameObj == m_gameObjects.end () или ++ gameObj == m_gameObjects.end ()
это операция NULL.

Еще одна вещь, которую вы делаетепостинкремент на итераторе в цикле for делает его преинкрементным.Это не имеет ничего общего с аварией.

0 голосов
/ 13 июля 2010

Когда вы говорите:

m_gameObjects.erase( gameObj );

будет вызван деструктор для предмета, содержащегося в удаляемом списке (если он есть). Из вашего вопроса не ясно, каков тип этой вещи, или ожидается ли этот вызов деструктора.

...