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

发布于 2024-09-08 20:14:13 字数 1534 浏览 2 评论 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 个游戏对象碰撞之间的无限循环。抱歉,无法从发布的代码中破译。

Note that the order can go either way (erase first then push back, just that this way doesn't require creating a local reference to the object).

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

The idea is that if the function finds an object colliding with the object passed, it adds that object to the end of the list, erases it from its current position, then returns the object. I don't think iterator invalidation is a problem since I am returning immediately after the erasure?

The code causes the program to crash.

P.S. cppreference says that erase "deletes" the object, but I assumed that this just removed it from the list. (If this is wrong, how can I remove an element by its location. The remove function doc I'm reading only allows passing the value of the object).

Edit: The location of the crash isn't always the same, but it occurs because of this code (i.e. if I revert it, acts normally). What causes a variably timed delayed crash? I do not want the object found to be destroyed.

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
Found the bug, when moving the object to the end of the list, caused infinite loop between 2 GameObjects colliding. Sorry, couldn't have been deciphered from code posted.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

你穿错了嫁妆 2024-09-15 20:14:13

当您说:

m_gameObjects.erase( gameObj );

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

When you say:

m_gameObjects.erase( gameObj );

the destructor for the thing contained in the list being erased (if it has one) will be called. It's not clear from your question what the type of this thing is, or if this destructor call is expected.

分分钟 2024-09-15 20:14:13

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

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

"m_gameObjects.splice( m_gameObjects.end(), m_gameObjects, gameObj );"
Do you want to move the gameObj to the last position in the list? That is what the above line suggests. If yes, then
if the gameObj == m_gameObjects.end() or ++gameObj == m_gameObjects.end()
it is a NULL operation.

One more thing, you are doing a post-increment on the iterator in the for loop make it pre-increment. This has nothing to do with the crash though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文