迭代器删除操作写法及解释

来源:互联网 发布:慢慢减肥知乎 编辑:程序博客网 时间:2024/05/22 02:06

1 迭代器是什么?

迭代器是一种典型的设计模式,与集合配套使用,其目的是隐藏集合中的内部成员,并且提供对集合成员的访问能力。其结构如下图所示;

Iterator Pattern

具体协作关系及实现方式,就不在此赘述了。

 

2 在迭代器上执行删除操作

下面以删除list中所有给定值的元素为例,介绍迭代器的一种常见写法及原理解释。

错误写法:

[cpp] view plaincopy
  1. std::list<int>::iterator it = listVar.begin();  
  2. while(it != listVar.end())  
  3. {  
  4.     // 相等,则删除当前位置并后移  
  5.     if (*it == iVar)  
  6.     {  
  7.         listVar.erase(it); // 删除当前位置  
  8.         it++; // 向后移动  
  9.     }  
  10.     // 不相等,则向后移动  
  11.     else  
  12.     {  
  13.         it++;  
  14.     }  
  15. }  
在erase之后,迭代器已变为无效,因此再执行++操作,其行为是未定义的。


正确写法一:

[cpp] view plaincopy
  1. std::list<int>::iterator it = listVar.begin();  
  2. std::list<int>::iterator = listVar.end();  
  3. while(it != listVar.end())  
  4. {  
  5.     // 相等,则删除当前位置并后移  
  6.     if (*it == iVar)  
  7.     {  
  8.         itNext = it;  
  9.         itNext++; // 先获取到当前位置的下一个位置  
  10.         listVar.erase(it); // 删除当前位置  
  11.         it = itNext; // 将下一个位置赋值给it  
  12.     }  
  13.     // 不相等,则向后移动  
  14.     else  
  15.     {  
  16.         it++;  
  17.     }  
  18. }  

在删除指定位置前,此时迭代器是有效的,先获取其下一个位置,然后删除当前位置,最后再将下一位置赋值给当前迭代器。这个方法是可行的,但是写法很冗余,其实这几步,一行就可以搞定


正确写法二:

[cpp] view plaincopy
  1. while(it != listVar.end())  
  2. {  
  3.     // 相等,则删除当前位置并后移  
  4.     if (*it == iVar)  
  5.     {  
  6.         listVar.erase(it++); // 删除当前位置并后移  
  7.     }  
  8.     // 不相等,则向后移动  
  9.     else  
  10.     {  
  11.         it++;  
  12.     }  
  13. }  
这种写法也是一种很典型的用法。

相信大家在平时写代码时也都是这么用的,但为什么这样写可行,可能有些同学就说不清楚了。

首先,it++是一个函数调用,其调用的函数为迭代器的operator++()方法,该方法将迭代器自身向后移动一个位置,同时其返回当前位置。

然后,erase执行时,传递进来的迭代器是当前位置的拷贝的一个临时迭代器,而it此时已经指向下一个位置了。

0 0
原创粉丝点击