这里有一小段代码,这让我们有点生气......
for (vector<QSharedPointer<Mine>>::iterator itMine = _mines.begin();
itMine != _mines.end();) {
auto point2 = shipFire[l].getBulletLine().p2();
if (_mines[pos]->checkCollision(point2)) { // _mines is a Vector<QSharedPointer<Mine>>
Explosion explosionMine(_mines[pos]->point());
_explosions.push_back(explosionMine);
itMine = _mines.erase(itMine);
bulletErased = true;
scoreFrame += 100;
}
else {
++itMine;
pos++;
}
}
问题是,itMine
正在删除我们vector<..<Mine>>
中的两个,并且正在使程序意外关闭
我们考虑过这个问题,想出了这个:我的所有迭代器在删除了我的一个之后都失效了,对吗?
但我们对如何更改我们的实际代码以适应新代码感到有些困惑?
主要问题是:我们如何重置这个呢?
ps:如果您有任何疑问,或者您需要更多代码来理解背后的逻辑,请随时提出更多问题!
最诚挚的问候,并提前感谢你。
答案 0 :(得分:0)
这个问题的一个非常罕见的解决方案是将当前位置与后退位置交换。然后可以删除最后一项而不会使任何迭代器失效。请参阅live example。
#include <iostream>
#include <vector>
#include <memory>
int main()
{
struct Mine
{
Mine( int id = 0 ): id( id ) { }
bool check_collision_point( int point ) const { return id % point == 0; }
int id;
};
auto mines = std::vector<std::shared_ptr<Mine>>{ 7 };
for( auto i = 0u; i < mines.size(); ++i )
{
mines[i] = std::make_shared<Mine>( i );
}
// save point outside loop
auto point = 2;
for( auto it = mines.begin(); it != mines.end(); )
{
// don't use mines[pos] in loop
if( (*it)->check_collision_point( point ) ){
std::iter_swap(it, mines.rbegin() );
mines.resize( mines.size() -1 );
}
else
++it;
}
for( auto it = mines.begin(); it != mines.end(); ++it)
std::cout << (*it)->id << " ";
}
答案 1 :(得分:0)
更新
for (auto itMine = _mines.begin(); itMine != _mines.end();){
auto point2 = shipFire[l].getBulletLine().p2(); // thomas : -> here we need to do it in the loop, to get every bullet position while looping.
if (_mines[pos]->checkCollision(point2)){
Explosion explosionMine(_mines[pos]->point());
_explosions.push_back(explosionMine);
if (_mines[pos]->checkCollision(point2)){
mines_to_be_deleted.push_back(*itMine);
shipFire.erase(it);
bulletErased = true;
scoreFrame += 100;
qDebug() << "Collision bullet mine";
}
}
//else
++itMine;
pos++;
}
for (auto itrDelete = mines_to_be_deleted.begin(); itrDelete != mines_to_be_deleted.end();)
{
_mines.pop_back(); // Here instead of that, we need to erase the current itr (here is our mistake)
//mines_to_be_deleted.erase(itrDelete);
//_mines.resize(_mines.size());
qDebug() << "mine deleted";
++itrDelete;
}
mines_to_be_deleted.clear();
此时我们想出了这个。 我们尝试了你告诉我们的所有内容,但没有一个有效,我们考虑将当前的itr交换到向量的末尾。谢谢你的帮助。
目前,该计划运行得非常好,但是当我们用一颗子弹击中一枚地雷时,一只手枪就会消失。
对于那些想要了解的人,我们找到了解决方案。
while(!mines_to_be_deleted.empty()) { // _mine_to_be_deleted is a QList<Sharedpointer<Mine>>
std::remove(begin(_mines),end(_mines),mines_to_be_deleted.front());
_mines.pop_back();
mines_to_be_deleted.pop_front();
}
使用std :: remove允许我们擦除Mine而不创建malloc()