在做个游戏,游戏中的子画面我都保存在vector里了
std::vector<ISprite*> m_arrSprites; //数组,保存所有的子画面
现在游戏在更新时,我要更新每个子画面所以,就有了下面的代码//更新游戏时,调用此函数
void CGameManager::onUpdate()
{
std::vector<ISprite*>::iterator it;
for (it = m_arrSprites.begin(); it != m_arrSprites.end(); )
{
if(*it)
(*it)->update();
}
}
//怪物类,在场景中添加怪物
class CMonster : public ISprite
{
}
//游戏中怪物的更新
void CMonster::update()
{
if (rand() % 20 == 0)  //这里我让它发射子弹,而子弹又是一个子画面类
m_pGameInstance->addSprite(shoot());
}
//这是向vector里加入子画面
void CGameManager::addSprite(ISprite* sprite)
{
m_arrSprites.push_back(sprite);
}不知我把问题描述清了没,简单点说就是我要遍历vector,在遍历的过程中,我又会push_back(),向vector中添加元素。
这样,就导致在vector里出错了,不知如何解决,谢谢大家!
或者,你可以教我一种方法,游戏中,怪物发射的子弹,如何添加到vector中,让CGameManager管理?

解决方案 »

  1.   

    应该是个同步问题,可以加个锁来实现。或者在更新时将当前m_arrSprites复制一份进行操作。
      

  2.   

    具体出什么错?shoot函数怎么写的?如果是多线程访问m_arrSprites,需要加锁。
      

  3.   

    it递增
    for (it = m_arrSprites.begin(); it != m_arrSprites.end(); )
        {
            if(*it)
                (*it)->update();
        }
      

  4.   

    错误跑到vector中了,_Myt& operator++()
    { // preincrement
    _SCL_SECURE_VALIDATE(this->_Mycont != NULL);
    _SCL_SECURE_VALIDATE_RANGE(_Myptr < ((_Myvec *)(this->_Mycont))->_Mylast);
    ++_Myptr;
    return (*this);
    }shoot()函数主要就是
    ISprite* sprite = new CBullet();
    基本就是这个。
      

  5.   

    多线程访问m_arrSprites的话,要同步.
      

  6.   

    我也觉得问题有点像同步。。
    可我没用到多线程,我的做法就类似下面:for(it = vector.begin(); it != vecotr.end(); ++it)
    {
      if(条件)
         vector.push_back();
    }这样就导致迭代器毁坏了,不知各位有没这样用过vector??
      

  7.   

    如果vector内的空间不足插入新的元素,那么会导致vector重新分配内存并释放原来的内存,这样会导致原来的迭代器失效。
    ++it就会出现问题
      

  8.   

    应该是这个原因,有什么办法解决这个问题吗?
    我要在遍历的过程中,还能push_back().
    现在我想的是,如果不能在遍历过程中push_back().那就等到遍历完成后,再向vector里插入数据。
      

  9.   

    在迭代的过程中,可以删除的。std::vector<ISprite*>::iterator it;
    for (it = m_arrSprites.begin(); it != m_arrSprites.end(); )
    {
         if ((*it)->isShouldBeDeleted()) //子画面更新完成后,检查是否该被删除
    {
    delete *it;
    it = m_arrSprites.erase(it); //STL::VECTOR的用法..
    }
    else
    ++it;
    }
      

  10.   

    可以使用[]操作符来索引元素,或者用*begin()+n
      

  11.   


    这才是正道(或者也可以用at方法来获取)。只要你保证下标不越界,就没问题。一般要用到迭代器的场合,都需要用一个同步对象来保护。 原因嘛,如11L所言。