我正在浏览Cinder的Box2D模板中的代码,并希望修改代码,以便我可以将框移到屏幕上并添加它们。我是C ++的新手,但基于我从其他SO帖子中学到的东西,我试图使用这个案例从矢量中删除框:
for( vector<b2Body*>::iterator boxIt = mBoxes.begin(); boxIt != mBoxes.end(); ++boxIt ) {
if( (*boxIt)->GetPosition().x > scaledX){
boxIt = mBoxes.erase(boxIt);
}
else {
Vec2f pos( (*boxIt)->GetPosition().x, (*boxIt)->GetPosition().y );
float t = toDegrees( (*boxIt)->GetAngle() );
glPushMatrix();
gl::translate( pos );
gl::rotate( t );
Rectf rect( -BOX_SIZE, -BOX_SIZE, BOX_SIZE, BOX_SIZE );
gl::drawSolidRect( rect );
glPopMatrix();
}
}
但是当“(* boxIt) - &gt; GetPosition()。x”第二次执行时,这会导致访问崩溃。有什么想法吗?
答案 0 :(得分:2)
擦除后你不应该++boxIt
。赋值已经将迭代器移动到下一个项目。
从for行中删除++boxIt
并将其放入else
。
答案 1 :(得分:1)
您观察到此类行为的原因是因为向量erase()
使现有迭代器无效。然后,您无法递增迭代器++boxIt
。但是erase()
返回一个新的迭代器,指向被删除的元素之后的元素。并且您可以使用此返回的迭代器继续迭代向量。
所以,你可能会这样编码:
vector<b2Body*>::iterator boxIt = mBoxes.begin();
while (boxIt != mBoxes.end();) {
if( (*boxIt)->GetPosition().x > scaledX){
boxIt = mBoxes.erase(boxIt);
}
else {
Vec2f pos( (*boxIt)->GetPosition().x, (*boxIt)->GetPosition().y );
float t = toDegrees( (*boxIt)->GetAngle() );
glPushMatrix();
gl::translate( pos );
gl::rotate( t );
Rectf rect( -BOX_SIZE, -BOX_SIZE, BOX_SIZE, BOX_SIZE );
gl::drawSolidRect( rect );
glPopMatrix();
boxit++;
}
}
见这里:
答案 2 :(得分:0)
您的问题是您正在擦除迭代器,然后继续迭代它。
对于向量every iterator and reference after the point of erase is invalidated.
(此处其他案例的概述:http://kera.name/articles/2011/06/iterator-invalidation-rules/)
您可以尝试使用erase with remove_if(后者实际上不会删除任何内容)