问题描述
我尝试包含可能导致这些问题的所有必要代码。 这段代码第二次运行时程序崩溃了:
for (int i = 0; i < player.projectiles.size(); i++)
{
bool temp = player.projectiles[i].move(begin,WIDTH);
if (temp == true)
{
player.projectiles[i].destroy();
player.projectiles.erase(player.projectiles.begin() + i);
}
}
Player.projectiles 是来自类 Projectiles 的对象向量。 成员函数 move 完美运行,函数 destroy 看起来像这样:
void Projectile::destroy()
{
delete this;
}
第一次循环运行一切正常,但第二次我的程序崩溃了,我不知道为什么。我怀疑这与删除对象有关。非常感谢任何帮助。
解决方法
您没有在 Projectile*
中存储 vector
指针,而是存储了实际的 Projectile
对象(如事实上,您的循环正在使用 Projectile
而不是 operator.
访问 operator->
类的成员)。因此,对这些对象中的任何一个调用 destroy()
绝对是错误的做法,因为您不拥有该内存! vector
会这样做,因此当它们从 vector
中移除时,包括当 vector
被清除或自身销毁时,它们会为您销毁每个对象。
话虽如此,您在遍历它的同时也在修改 player.projectiles
,因此您的循环将至少在删除元素时 跳过元素,并且 甚至可能越界。您不得在调用 i
的迭代中增加 erase()
计数器,例如:
for (size_t i = 0; i < player.projectiles.size(); )
{
if (player.projectiles[i].move(begin,WIDTH))
player.projectiles.erase(player.projectiles.begin() + i);
else
++i;
}
或者,vector::erase()
返回一个迭代器到被擦除元素之后的下一个元素,所以让你的循环使用迭代器而不是索引,例如:
for(auto iter = player.projectiles.begin(); iter != player.projectiles.end(); )
{
if (iter->move(begin,WIDTH))
iter = player.projectiles.erase(iter);
else
++iter;
}
或者,您可以通过 erase-remove 使用 std::remove_if()
习语来替换整个循环,例如:
#include <algorithm>
player.projectiles.erase(
std::remove_if(player.projectiles.begin(),player.projectiles.end(),[=](auto &projectile) { return projectile.move(begin,WIDTH); }
),player.projectiles.end()
);
或者,C++20 中的 std::erase_if()
:
std::erase_if(
player.projectiles,WIDTH); }
);