向量迭代器在新对象的 push_back() 之后不兼容

Vector iterator incompatible after push_back() of a new object

本文关键字:push back 不兼容 之后 对象 迭代器 新对象 向量      更新时间:2023-10-16

我有一个Entity类,所有对象(MissilesSpacesshipStarsExplosions)都继承自这些类的实例,每当创建这些类的实例时,Entity 的构造函数都会将"this"添加到其所有实例的向量列表中,就像这样:

std::vector<Entity*> Entity::instances;
Entity::Entity()
{
instances.push_back(this);
}

这工作得很好,因为我可以遍历每个实例并通过 e->Render() 或 e->Update() 等执行其方法。

奇怪的是,它适用于其他任何地方,但在一个特定的地方。 它在这里工作: 核心.cpp

for (int i = 0; i < 128; i++)
{
stars[i] = new Star();
stars[i]->position.x = rand() % (screenWidth + 1);
stars[i]->position.y = rand() % (screenHeight + 1);
stars[i]->angle = rand() % 360;
stars[i]->boundingbox.w = 2 + rand() % 7;
stars[i]->boundingbox.h = stars[i]->boundingbox.w;
}
for (int i = 0; i < 16; i++)
{
meteorites[i] = new Meteorite();
meteorites[i]->Spawn();
}

但是在这里..它弹出"矢量迭代器不兼容">

陨石.cpp

void Meteorite::TakeDamage()
{
health -= 5;
if (health <= 0)
{
Missile* explo = new Missile();
explo->position.x = position.x;
explo->position.y = position.y;
Spawn();
}
}

我完全一无所知 - 并不是说我以与通常不同的方式创建这些元素。

#EDIT我认为这也很重要,Meteorite::Update() 可以检测碰撞并在创建实例的地方运行 TakeDamage():

for each (Entity* e in Entity::instances)
{
if (e == this)
{
continue;
}
if (e->entClass == "ENTITY_MISSILE")
{
Missile* m = (Missile*)e;
if (abs(position.x - m->position.x) * 2 < (boundingbox.w + m-
>boundingbox.w))
{
if (abs(position.y - m->position.y) * 2 < (boundingbox.h + m-
>boundingbox.h))
{
TakeDamage();
break;
}
}
}
}

请注意,当您在std::vector上调用push_back时,迭代器将失效(强调我的):

如果新的 size() 大于 capacity(),则所有迭代器和引用(包括过去结束的迭代器)都将失效。否则,只有过去结束迭代器失效。

因此,在for循环中,当调用TakeDamage时,您构造了一个Missile(随后调用Entity::Entity()instances.push_back(this)),您将使迭代器无效。

您要么需要遍历索引而不是迭代器,要么跟踪哪些对象需要调用TakeDamage()它们并在完成迭代后调用它们,或者创建迭代instances的副本。

请注意,我从未见过语法for each (... in ...)但大概它正在使用迭代器。


你提到问题中的代码在Meteorite::Update内运行,你还提到

这工作得很好,因为我可以遍历每个实例并通过 e->Render() 或 e->Update() 等执行其方法。

您很可能正在遍历所有instances,调用Update,并在该调用TakeDamage中使您的instances无效。在迭代instances时在TakeDamage内调用push_back绝对是您的问题。

尝试:for(Entity* e : Entity::instances)而不是你for each的东西