推回对象,然后在std :: list中的先前位置擦除它

时间:2010-07-12 22:15:23

标签: c++ list iterator stdlist

请注意,订单可以采用任何一种方式(首先擦除然后再推回,只需这样就不需要创建对象的本地引用)。

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

这个想法是,如果函数发现一个对象与传递的对象发生冲突,它会将该对象添加到列表的末尾,从当前位置删除它,然后返回该对象。我不认为迭代器失效是一个问题,因为我在擦除后立即返回?

代码导致程序崩溃。

P.S。 cppreference说擦除“删除”了对象,但我认为这只是从列表中删除它。 (如果这是错误的,我怎么能按其位置删除元素。我正在读取的删除函数doc只允许传递对象的值。)

编辑:崩溃的位置并不总是相同,但是由于此代码而发生(即如果我还原它,则正常运行)。什么导致可变的定时延迟崩溃?我不希望找到的对象被破坏。

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之间发生无限循环冲突。对不起,无法从发布的代码中解密。

2 个答案:

答案 0 :(得分:0)

当你说:

m_gameObjects.erase( gameObj );

将被调用的列表中包含的东西的析构函数(如果有的话)将被调用。从你的问题中不清楚这个东西的类型是什么,或者是否期望这个析构函数调用。

答案 1 :(得分:0)

“m_gameObjects.splice(m_gameObjects.end(),m_gameObjects,gameObj);”
你想将gameObj移动到列表中的最后位置吗?这就是上述线所表明的。如果是,那么
 如果gameObj == m_gameObjects.end()或++ gameObj == m_gameObjects.end()
 它是一个NULL操作。

还有一件事,你在for循环中对迭代器进行后递增,使其预先递增。这与坠机无关。