2013-08-28 3 views
0

У меня есть несколько векторов, которые содержат объекты и у меня есть вложенное ряд петель, чтобы добраться до объекта я хочуC++ удаление из вектора объектов

if (_dir->Instance()->isDebug()) 
{ 
    Utils::LogTextWithInt("growing timers size: ", _glo->Instance()->getGrowingTimers().size()); 
    for (int i=0; i < _glo->Instance()->getGrowingTimers().size(); i++) 
    { 
     GrowingTimer _growingTimer = _glo->Instance()->getGrowingTimers().at(i); 

     std::cout << "growing timer Field id and plant id: " << _growingTimer.getFieldID() << " - " 
        << _growingTimer.getPlantID() << std::endl; 
    } 
} 

std::vector<GrowingTimer>::iterator _gtIterB = _glo->Instance()->getGrowingTimers().begin(); 

for (_gtIterB; _gtIterB != _glo->Instance()->getGrowingTimers().end(); ++_gtIterB) 
{  
    for (std::vector<Field>::iterator _fIterB = _glo->Instance()->getFields().begin(); 
     _fIterB != _glo->Instance()->getFields().end(); ++_fIterB) 
    {   
     if (_gtIterB->getFieldID() == _fIterB->getFieldNumber()) 
     { 
      for (std::vector<Plant>::iterator _pIterB = _fIterB->getPlants().begin(); 
       _pIterB != _fIterB->getPlants().end();) 
      { 
       if (_gtIterB->getPlantID() == _pIterB->getPlantID()) 
       { 
        Utils::LogText("gt and plant ID's match"); 
        Utils::LogTextWithInt("Plant ID after matching: ", _pIterB->getPlantID()); 

        // Wiggle our plant. 
        Utils::wiggleNode(_pIterB->getPlantSprite(), 10.0f, 5.0f); 

        _pIterB->setPlantStoppedGrowing(true); 

        _gtIterB = _glo->Instance()->getGrowingTimers().erase(_gtIterB); 

        ++_pIterB; 
       } 
       else 
       { 
        ++_pIterB; 
       } 

      } 
     } 
    } 
} 

Выход:

growing timers size: 2 
growing timer Field id and plant id: 7620 - -2130819608 
growing timer Field id and plant id: 7620 - -2130802800 
gt field id: 7620 
gt plant id: -2130819608 
gt and plant ID's match 
Plant ID after matching: -2130819608 
deleted 
gt and plant ID's match 
Plant ID after matching: -2130802800 
deleted 
gt field id: 7620 
gt plant id: -2130802800 
gt and plant ID's match 
Plant ID after matching: -2130802800 

Я врезаться после всего этого:

0x209eff0: addb %ah, %gs:115(%ecx,%ebp,2) 
0x209eff5: jo  0x209f063     ; "nitWithCondition:" 
0x209eff7: popal 
0x209eff8: jns 0x209f048     ; "'v'" 
0x209effa: popal 
0x209effb: insl 
0x209effc: incl %esi 
0x209effe: outsl 
0x209efff: jb  0x209f04c     ; "ckBeforeDate:" 
0x209f001: jns 0x209f03e     ; "Name:" 
0x209f004: jbe 0x209f067     ; "ithCondition:" 
0x209f006: insb 
0x209f007: jne 0x209f06e     ; "ition:" 
0x209f009: cmpb (%eax), %al 
0x209f00b: popl %edi 
0x209f00c: jo  0x209f080     ; "lSinceNow" 

в основном теперь, когда у меня есть матч и я действую на него, я хочу, чтобы удалить позицию _gIterB, поскольку он больше не нужен. Этот вектор продолжает добавляться в качестве «трекера», если вы выполняете синхронизированные события, которые выполняются так, что, когда таймеры закончены, мы знаем, для какого объекта был таймер, и можем вернуться к нему, чтобы сделать следующие шаги.

EDIT: вектор GrowingTimer хранит идентификатор fieldID и PlantID, который «растет», поэтому мы можем вернуться к нему.

В поле «Поля» хранятся все поля, которые есть у пользователя, и в качестве члена каждый объект поля имеет вектор растений в поле. 8 растений до 1 поля.

Каждое поле, которое пользователь создает, имеет уникальный идентификатор, на выходе ниже есть одно поле с двумя растениями в нем.

+0

Поскольку векторы использовать массив в качестве основного хранения, удаление элементов, отличной от вектора конца позиции заставляет контейнер переместить все элементы после того, как сегмент стирается до их новых позиций. Итераторы недействительны после стирания элемента. Обычно я делаю это, чтобы сохранить индекс объекта, который нужно удалить, в отдельный вектор, а затем запустить и удалить эти элементы после того, как kloop, чтобы найти их, закончен. –

+0

может несколько полей имеют одинаковый идентификатор? Потому что, если нет, это может быть упрощено. –

+0

@MooingDuck Я сделал надпись выше, чтобы описать это. – Jason

ответ

0
for (auto _gtIterB=grow_timers.begin(); _gtIterB!=grow_timers.end(); ++_gtIterB) {  
    ... 
    _gtIterB = _glo->Instance()->getGrowingTimers().erase(_gtIterB); 
    .... 
} 

В принципе, здесь есть две проблемы.

  • когда вы стираете _gtIterB, вы назначаете его положение следующего расти таймер. Это означает, что вы пропустили сравнение этого growtimer со многими растениями. Я предполагаю, что это плохо, но, вероятно, не вызывает вашего краха.
  • Если вы удалите _gtIterB, когда это последний действительный growtimer, он установлен в конце итератора, тогда, когда вы перейдете к следующей части цикла for, вы снова получите ++_gtIterB, заставив его пройти мимо конца, в результате чего кто знает, что произойдет. Это определенно плохо.

Я не уверен, что любой из них вызывает ваш крах.

Но вот моя интерпретация коды, который быстрее и не глубоко вложенный: http://ideone.com/zcfnv8

+0

Я пытался понять, что здесь описано: http://stackoverflow.com/questions/991335/how-to-erase-delete-pointers-to-objects-stored-in-a-vector – Jason

+0

@ Джейсон: Вы имеете в виду часть который говорит 'for (it = Entities.begin(); it! = Entities.end();)' вместо того, что у вас есть? –

+0

они также, похоже, увеличивают итератор, который, как я думал, был немного странным, поскольку вы можете сделать это как часть цикла for. – Jason

Смежные вопросы