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 个 GameObjects 碰撞之间的无限循环。抱歉,无法从发布的代码中破译。

4

2 回答 2

0

当你说:

m_gameObjects.erase( gameObj );

将调用包含在被删除列表中的事物的析构函数(如果有的话)。从您的问题中不清楚这个东西的类型是什么,或者是否需要这个析构函数调用。

于 2010-07-12T22:30:39.797 回答
0

“m_gameObjects.splice(m_gameObjects.end(), m_gameObjects, gameObj);”
是否要将 gameObj 移动到列表中的最后一个位置?这就是上面的行所暗示的。如果是,那么
如果 gameObj == m_gameObjects.end() 或 ++gameObj == m_gameObjects.end()
它是一个 NULL 操作。

还有一件事,您正在 for 循环中对迭代器进行后增量,使其预增量。但这与崩溃无关。

于 2010-07-12T22:52:42.973 回答