【问题标题】:Vector Iterator within an iterator error迭代器错误中的向量迭代器
【发布时间】:2013-02-22 11:34:13
【问题描述】:

为我的作品集开发一款小行星游戏。使用以下代码块解决错误。错误只是迭代器不可延迟,但我已经缩小了错误范围。在我给你看代码后,我会谈论这个:

void Game::Update()
{
if (elapsedTime > REFRESH_RATE)
{
    player->Update(elapsedTime);

    std::vector<Asteroid*>::iterator iterator= bigAsteroids.begin();
    std::vector<Bullet*>::iterator iter = bullets.begin();

    // *********************** //
    while (iterator!= bigAsteroids.end())
    {
        if (*iterator != nullptr) // Checks to see if player is colliding with an asteroid and updates the asteroid
        {
            player->CheckCollisionsAsteroid( *iterator );

            // *********************** // Checks to see if bullet is colliding with asteroid 
            while (iter != bullets.end())
            {
                if (*iter != nullptr)
                {
                    if ((*iter)->CheckCollisionsAsteroid( **iterator ))
                    {
                        size_t i = iterator - bigAsteroids.begin();
                        iter = bullets.erase(iter);
                        iterator = bigAsteroids.erase(iterator);
                        printf("\nAsteroid destroyed at position %i", i);
                    }
                    else
                    {
                        ++iter;
                    }
                }
            }
            iter = bullets.begin(); // Reset the bullet iterator else we'd only get to check 1 asteroid

            // *********************** //
            if (*iterator != nullptr && iterator != bigAsteroids.end()) { (*iterator)->Update(elapsedTime); }
        }
        if (*iterator != nullptr && (iterator!= bigAsteroids.end()))
        {++iterator;}
    }
    // *********************** //
    Clock.Reset(); 
}
}

如果看起来有点乱,这里有一个简短的解释:

当迭代器通过每个小行星时,我检查玩家是否与每个小行星发生碰撞。 目前这没有任何作用

然后我遍历我的子弹向量,检查每个子弹与当前的小行星。如果发生碰撞,我会销毁并擦除子弹和小行星,并打印出被摧毁的小行星在向量中的位置。

完成后,我会重置下一颗小行星的子弹迭代器。

我目前的主要问题是 (*iterator)

只有在我擦除小行星矢量中的最后一个对象时才会出现此问题。我知道擦除将迭代器返回到下一个对象 - 如果下一个对象不存在,则会引发错误(因为迭代器然后指向 nullptr,对吗?)。我正在检查 nullptr 无济于事..

有没有人可以提供任何建议或帮助?将不胜感激,我已经挠了好几个小时了!

【问题讨论】:

  • 如果您以迭代器引用的名称命名迭代器,这将显着提高代码的可读性,例如itAsteroiditBullet.
  • @Angew 我得到了很多哈哈,我一直在重写代码,所以目前在'iter'或'iterator'上输入bulletIter或asteroidIter..:P最终版本将实现这些,谢谢. BoB 嗯.. 我会回复你的,谢谢你的帮助

标签: c++ iterator stdvector 2d-games


【解决方案1】:

问题是当你摧毁最后一颗小行星时,iterator 将被设置为bigAsteroids.end()(通过分配给erase() 的结果)。然后在内部while 循环终止后,取消引用iterator。无法取消引用过去的迭代器。

您必须切换检查顺序:

if (iterator != bigAsteroids.end() && *iterator != nullptr)

【讨论】:

  • 这不是最后一颗小行星。这可能是我拍摄的第一颗小行星。如果它是矢量中的最后一个小行星(如最后的小行星),则抛出错误。我想我目前还没有设法找到一颗小行星射击!哈哈
  • 他的意思是:当你调用bigAsteroids.erase(iterator)时,iterator被设置为bigAsteroids.end()*iterator != nullptr 会失败,iterator != bigAsteroids.end() 会返回false,所以切换条件的顺序,应该没问题
  • 噢噢噢噢。我懂了。我确实改变了它:if (itAsteroid != bigAsteroids.end()) { (*itAsteroid)-&gt;Update(elapsedTime); } 这仍然会导致错误。但是,然后我更改了下面的行:if ( itAsteroid!= bigAsteroids.end() &amp;&amp; *itAsteroid != nullptr ) {++itAsteroid;} 它按照你说的做了。我对你们做了什么:P 谢谢你们!
猜你喜欢
  • 1970-01-01
  • 2012-06-18
  • 1970-01-01
  • 1970-01-01
  • 2017-08-29
  • 2011-11-15
  • 2017-12-29
相关资源
最近更新 更多