Pen*_*hou 4 c++ vector shared-ptr
像下面的代码一样,m_vSprites是shred_ptr的向量,如果他的一个元素更新失败,我想从向量中删除它,但是当我想使用erase时我的代码崩溃了.但我不知道为什么,任何人都可以提供帮助?
我需要使用擦除的原因是因为我的应用程序会不断地在向量中添加元素,但如果某些元素满足其杀死条件,它还会不断地从向量中擦除对象.如果我没有删除它,那么当程序工作时,向量会变得很大!
RECT rcOldSpritePos;
typedef boost::shared_ptr<Sprite> SmartSprite;
vector<SmartSprite>::iterator siSprite;
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end();)
{
// Save the old sprite position in case we need to restore it
rcOldSpritePos = (*siSprite)->getPosition();
if (!((*siSprite)->update()))
{
// Kill the sprite
//siPreviousSprite = siSprite-1;
siSprite = m_vSprites.erase(siSprite);
}
else
{
siSprite++;
// See if the sprite collided with any others
if (checkSpriteCollision(*siSprite))
// Restore the old sprite position
(*siSprite)->setPosition(rcOldSpritePos.left, rcOldSpritePos.top);
}
}
Run Code Online (Sandbox Code Playgroud)
我已根据有人的建议修改了代码,但在删除功能方面仍然失败,请问有人有什么建议吗?
更多信息我如何在vecotr中添加元素
这有什么问题?
SmartSprite sprite;
if (0 < enemies.size())
{
// Pick a random enemy to drop bomb
size_t nRandEnemy = (rand() % enemies.size());
RECT rRandEnemy = enemies.at(nRandEnemy)->getPosition();
sprite.reset(new BombSprite(m_system, rRandEnemy.right-OBJECTSIZE/2,
rRandEnemy.bottom));
m_vSprites.push_back(sprite);
}
Run Code Online (Sandbox Code Playgroud)
我的精灵课没有任何析构函数......
另外一个信息是,当我调试时,发现它在擦除内部函数时崩溃:_Destroy(_Mylast - 1,_Mylast);
问题解决了!原因是在我的Sprite类中,我将其包装为智能指针,并创建另一个智能指针作为其成员变量.现在我没有使用智能指针成员变量,系统没有再次崩溃....我将继续思考为什么我不能在该类中使用智能指针,当从向量中擦除精灵时,它的成员变量有关系吗?如果只使用原始指针而不是起诉智能指针,我还需要删除该成员变量吗?
如果你要擦除的迭代器是向量的开始迭代器,那么这个;
siPreviousSprite = siSprite - 1;
Run Code Online (Sandbox Code Playgroud)
是未定义的行为.像这样重构你的循环:
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); )
{
rcOldSpritePos = (*siSprite)->getPosition();
if (!((*siSprite)->update()))
{
// Kill the sprite
siSprite = m_vSprites.erase(siSprite);
}
else
{
++siSprite;
}
}
Run Code Online (Sandbox Code Playgroud)
如果仍有崩溃,那么你的精灵类一定有问题.
我会尝试使用擦除删除惯用法。
您可能想要公开bool精灵类中的一个属性,并检查它是否要从true向量中删除精灵。像这样的东西(用VC10/VS2010 SP1测试的代码):
#include <algorithm>
#include <iostream>
#include <memory>
#include <ostream>
#include <vector>
using namespace std;
struct Sprite
{
explicit Sprite(int spriteId)
: kill(false)
, id(spriteId)
{
}
int id;
bool kill;
};
int main()
{
typedef shared_ptr<Sprite> SmartSprite;
typedef vector<SmartSprite> SpriteArray;
SpriteArray sprites;
for (int i = 0; i < 5; i++)
sprites.push_back( make_shared<Sprite>(i*11) );
for (auto it = sprites.begin(); it != sprites.end(); ++it)
cout << (*it)->id << " ";
cout << endl;
sprites[2]->kill = true;
sprites[3]->kill = true;
// Remove sprites with kill flag set
sprites.erase
(
remove_if
(
sprites.begin(),
sprites.end(),
[](const SmartSprite& ps){ return ps->kill; }
),
sprites.end()
);
for (auto it = sprites.begin(); it != sprites.end(); ++it)
cout << (*it)->id << " ";
cout << endl;
}
Run Code Online (Sandbox Code Playgroud)
输出:
0 11 22 33 44
0 11 44
Run Code Online (Sandbox Code Playgroud)
如果siSprite == m_vSprites.begin()那么siSprite-1就不合法。编写这种循环的通常方法是
for (siSprite = m_vSprites.begin(); siSprite != m_vSprites.end(); )
{
rcOldSpritePos = (*siSprite)->getPosition();
if ((*siSprite)->update())
{
++siSprite;
}
else
{
siSprite = m_vSprites.erase(siSprite);
}
}
Run Code Online (Sandbox Code Playgroud)
不确定这是否能真正解决您的问题,因为您的错误可能是完全无关的。
| 归档时间: |
|
| 查看次数: |
5655 次 |
| 最近记录: |