【问题标题】:Erasing a specific instance of an object from a vector从向量中删除对象的特定实例
【发布时间】:2013-10-28 22:45:07
【问题描述】:

我有一个类 Circle,我用这些来跟踪它的实例:

Circle *f1;
vector<Circle> list;
vector<Circle>::iterator it;

我设法创建了多个圈子并让它们四处走动。如何删除 Circle 的特定实例?例如,如果某个圆圈撞到墙上,那么它应该被擦除。我查看了其他问题,我什至尝试了他们给出的代码,但没有运气。这是我目前得到的:

for (it = list.begin(); it != list.end(); ++it) {

    it->x += 1;

    if (it->x == ofGetWindowWidth()) {
        list.erase(it);
    }
}

我已经让其他语句与 if 语句一起使用,例如反转它们的运动方向。 list.erase(它);是我从这里得到的一行代码,我不明白为什么它会导致我的程序崩溃。

【问题讨论】:

    标签: c++ vector stl erase


    【解决方案1】:
    for (it = list.begin(); it != list.end(); /* nothing here */) {
    
        it->x += 1;
    
        if (it->x == ofGetWindowWidth()) {
            it = list.erase(it);
        } else {
            ++it;
        }
    }
    

    您的原始代码的问题在于,擦除一个元素会使指向该元素的迭代器无效 - 您接下来尝试递增的迭代器正是该迭代器。这表现出未定义的行为。

    【讨论】:

      【解决方案2】:

      list.erase 使擦除元素的迭代器无效。因此,在删除“it”指向的元素后,“it”将失效,并且在 for 循环体之后的 ++it 可能会使您的程序崩溃。 将您的代码重写为类似于以下内容的代码应该可以防止崩溃:

      for(it=list.begin();it!=list.end(); ) {
          //your code
          if(it->x==ofGetWindowWidth())
              it=list.erase(it);
          else
              ++it;
      }
      

      【讨论】:

        【解决方案3】:

        上面使用erase()的代码的问题是当元素被擦除时它使it的内容无效。你可以使用,例如,这个:

        for (it = list.begin(); it != list.end(); ) {
            it->x += 1;
        
            if (it->x == ofGetWindowWidth()) {
                list.erase(it++);
            }
            else {
                ++it;
            }
        }
        

        使用erase() 的分支将保留的迭代器iterase() 元素之前移出其当前位置。只有从it++ 返回的临时对象无效。当然,要让这个循环工作,你不能无条件地递增it,即非erase()ing 分支需要自己的递增。

        【讨论】:

          【解决方案4】:

          您可以将擦除与remove_if 一起使用。这也适用于删除多个元素。在你的情况下是

          list.erase(std::remove_if(list.begin(), list.end(),
                  [](const Circle& c){return c.x == ofGetWindowWidth();},list.end()), 
          

          整数示例:

          #include <algorithm>
          #include <vector>
          #include <iostream>
          
          int main()
          {
              std::vector<int> str1 = {1,3,5,7};
              str1.erase(std::remove_if(str1.begin(), str1.end(),
                                        [](int x){return x<4 && x>2;}), str1.end());
             for(auto i : str1) std::cout << i ;
          }
          

          打印 157

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2017-03-30
            • 2014-05-05
            • 1970-01-01
            • 1970-01-01
            • 2017-06-22
            • 2014-04-28
            • 1970-01-01
            相关资源
            最近更新 更多