2010-07-12 1 views
0

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

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

Идея заключается в том, что если функция находит объект сталкивающийся с объектом, переданным, он добавляет, что объект в конце списка, стирает его из текущего положения, а затем возвращает объект. Я не думаю, что недействительность iterator является проблемой, так как я возвращаюсь сразу после стирания?

Код вызывает сбой программы.

P.S. cppreference говорит, что стирание «удаляет» объект, но я предположил, что это просто удалило его из списка. (Если это не так, как я могу удалить элемент по его местоположению. Функция doc remove, которую я читаю, позволяет передавать значение объекта).

Редактировать: Место аварии не всегда одно и то же, но оно происходит из-за этого кода (т. Е. Если я его возвращаю, действует нормально). Что вызывает чередующуюся задержку с переменным временем? Я не хочу, чтобы объект был уничтожен.

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 GameObjects сталкивающихся. Извините, не мог быть расшифрован из отправленного кода.

+0

Если это 'std :: list', вы можете вызвать' splice() ', чтобы переместить узел из его текущего местоположения в конец списка, а не копировать элемент и стирать его из его оригинальное местоположение. –

+0

m_gameObjects.splice (m_gameObjects.end(), m_gameObjects, gameObj); return m_gameObjects.back(); все еще, похоже, авария. – person

+2

Ничего общего с вопросом, но могу ли я предположить, что использование более коротких имен переменных сделает ваш код более понятным. Это, очевидно, связано с игрой, поэтому почему все должно быть префикс «игры»? И все вещи - объекты, поэтому gameObj, otherObj и gameObjects - все это бессмысленно - придумайте короткие, не общие имена. – 2010-07-12 22:41:25

ответ

0

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

m_gameObjects.erase(gameObj); 

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

+0

Спасибо. Все еще падает, когда я использую сплайсинг, хотя ... будет редактировать. Я отправлю всю функцию. Вызов деструктора не ожидается. – person

0

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

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

Смежные вопросы