首页 > 代码库 > 5_STL设计理念_迭代器
5_STL设计理念_迭代器
他山之石,可以攻玉。
http://blog.csdn.net/jxh_123/article/details/30793397?utm_source=tuicool&utm_medium=referral
重点:
1、迭代器iterator就是一种智能指针,它对原始指针进行了封装,并且提供一些等价于原始指针的操作,做到既方便又安全。
2、迭代器是连接容器和算法的一种重要桥梁。
find函数的函数原型为:template<class _InIt,class _Ty> _InIt find(_InIt _First, _InIt _last, const _Ty & _val)
从find函数原型可以看出find函数是一个函数模板,函数的形参中前两个参数为_InIt,该参数是InputIterator的缩写,最后一个参数则是一个任意类型变量的引用。
我们在使用find函数时,传入的实参为find(vec.begin(),vec.end(),7)。
这样我们的形参迭代器就将算法find和容器vector联系起来了,从这个角度我们可以很容易理解为什么说迭代器是算法和容器的联系的桥梁了。
原因:可以用派生类对象作为实参传递给以基类类型作为形参的函数,所以find函数中的vec.begin()作为实参,以输入迭代器类型作为形参,两者可以达到虚实相结合的目的而不会出错。
所以说,迭代器为各类算法和和各类容器提供了一个相互沟通的平台。
致使迭代器失效的操作:
一、使vector迭代器失效的操作
分析:vector是一个动态数组,push_back后,其后都后移一位,导致指向其后元素的迭代器失效;
C++为vector预分配一部分空间,如果插入操作导致空间不够用,就另外申请一个大的空间(一般为原有空间的2倍),并将原有元素赋值到新空间,销毁就空间。
1.向vector容器内添加元素(push_back,insert)
向vector容器添加元素分以下两种情况:
1)若向vector添加元素后,整个vector重新加载(即重新申请空间),即前后两次vector的capacity()的返回值不同时,此时该容器 内的所有元素对应的迭代器都将失效。
2)若该添加操作不会导致整个vector容器加载,则指向新插入元素后面的那些元素的迭代器都将失效。
2,删除操作(erase,pop_back,clear)
vector执行删除操作后,被删除元素对应的迭代器以及其后面元素对应的迭代器都将失效。
3.resize操作:调整当前容器的size
调整容器大小对迭代器的影响分如下情况讨论:
A.若调整后size>capacity,则会引起整个容器重新加载,整个容器的迭代器都将失效。
B.若调整后size<capacity,则不会重新加载,具体情况如下:
B1.若调整后容器的size>调整前容器的size,则原来vector的所有迭代器都不会失效;
B2.若调整后容器的size<调整前容器的size,则容器中那些被切掉的元素对应的迭代器都将失效。
4.赋值操作(v1=v2 v1.assign(v2))
会导致左操作数v1的所有迭代器都失效,显然右操作数v2的迭代器都不会失效。
5.交换操作(v1.swap(v2))
由于在做交换操作时,v1,v2均不会删除或插入元素,所以容器内不会移动任何元素,故v1,v2的所有迭代器都不会失效。
二、 使deque迭代器失效的操作
分析:deque是双端数组,头尾插入是向外延伸,中间元素不变。使用insert在内部插入,会导致迭代器失效。
1.插入操作(push_front,push_back,insert)
deque的插入操作对迭代器的影响分两种情况:
A.在deque容器首部或尾部插入元素不会是任何迭代器失效;
B.在除去首尾的其他位置插入元素会使该容器的所有迭代器失效。
2.删除操作
A.在deque首、尾删除元素只会使被删除元素对应的迭代器失效;
B.在其他任何位置的删除操作都会使得整个迭代器失效。
三、使list/map/set迭代器失效的操作
由于list/map/set容器内的元素都是通过指针连接的,list实现的数据结构是双向链表,而map/set实现的数据结构是红黑树,故这些容器的插入和删除操作都只需更改指针的指向,不会移动容器内的元素,故在容器内增加元素时,不会使任何迭代器失效。
而在删除元素时,仅仅会使得指向被删除的迭代器失效。
使用map时注意:STL中map这种关联容器的erase函数返回为void,不像顺序容器,返回删除元素的下一个元素
if(*it == value) map.erase(it++); //利用后置++的性质else ++it;
i++返回值是一个临时变量,重载时参数使用一个哑元int,以与++i分开,达到重载的目的;
成员函数法(隐含this指针):后置++重载
int operator++(int){ int tem = *this; ++*this; rerurn tem;}
对于顺序容器可以:
if(*it == value) it = vector.erase(it); //顺序容器删除操作,返回删除元素的下一个元素的迭代器位置else ++it;
5_STL设计理念_迭代器