C++STL 之 迭代器
说道stl,迭代器都是一个无法回避的话题,迭代器在stl中起着一个中介层的作用,一侧是标准的容器类,另一侧则是算法(algorithm).
1.迭代器与指针
迭代器是指向某个元素集合中指向某个元素的物体,从这一点上看,他和指针很类似,只是多了一层封装,但是迭代器和指针却又有所不同.
那么迭代器是不是指针呢?要看容器而定,由上可知,vector的迭代器是指针,list的迭代器就不是指针,而是object利用operator overloading使它表面上的操作像指针而已,但并不是一个指针。迭代器除了因为vector因为较简单,所以使用指针外,其他容器的迭代器都是一种智能指针,因为其操作跟指针一样,你可以将它当成指针方式使用,不过他仍然不是指针。
(想要了解更多关于迭代器与指针的内容可以点击下面的网站
2.迭代器种类
根据STL中的分类,iterator包括:
Input Iterator:只能单步向前迭代元素,不允许修改由该类迭代器引用的元素。
Output Iterator:该类迭代器和Input Iterator极其相似,也只能单步向前迭代元素,不
同的是该不同的是该类迭代器对元素只有写的权力。
Forward Iterator:该类迭代器可以在一个正确的区间中进行读写操作,它拥有Input Iterator的所有特性,以及单步向前迭代元素的能力。其具有写的特性.
Bidirectional Iterator:该类迭代器是在Forward Iterator的基础上提供了单步向后迭代元素的能力.
Random Access Iterator:该类迭代器能完成上面所有迭代器的工作,它自己独有的特性就是可以像指针那样进行算术计算,而不是仅仅只有单步向前或向后迭代。
以上箭头表示继承关系.
网上很多材料都froward和output的关系设定为继承关系,实际上是错误的.
为了更为明显的表示上面的关系我将写了下面的一组表格
属性 | 操作 | iutput | output | forwaid | bidrectional | Random access |
构造 复制构造 析构 | X a; X b(a); ~a; |
√ |
√ |
√ |
√ |
√ |
比较(相等或者不相等)操作(只有在同域中才有意义) | a==b |
√ |
|
√ |
√ |
√ |
解引用 | *a |
√ |
√ |
√ |
√ |
√ |
前向叠加操作 | ++a |
√ |
√ |
√ |
√ |
√ |
后向叠加操作 | --a |
|
|
|
√ |
√ |
二者赋值(在C11中给的是不必须的) | t = u |
√ |
|
√ |
√ |
√ |
交换(C11中出现) | swap(a,b) |
√ |
√ |
√ |
√ |
√ |
修改内部的值 | *a = t |
|
√ |
√ |
√ |
√ |
+ - 操作类似于指针 |
|
|
|
|
|
√ |
大于小于的比较 |
|
|
|
|
|
√ |
+= -=操作 |
|
|
|
|
|
√ |
支持移位操作([]符号,其实有了+ -知道这是可以模拟的) |
|
|
|
|
|
√ |
如果想要了解迭代器的函数可以参考这个网站
三、应用
1)它支持以不同的方式遍历一个聚合.复杂的聚合可用多种方式进行遍历,如二叉树的遍历,可以采用前序、中序或后序遍历。迭代器模式使得改变遍历算法变得很容易: 仅需用一个不同的迭代器的实例代替原先的实例即可,你也可以自己定义迭代器的子类以支持新的遍历,或者可以在遍历中增加一些逻辑,如有条件的遍历等。
2)迭代器简化了聚合的接口. 有了迭代器的遍历接口,聚合本身就不再需要类似的遍历接口了,这样就简化了聚合的接口。
3)在同一个聚合上可以有多个遍历 每个迭代器保持它自己的遍历状态,因此你可以同时进行多个遍历。
4)此外,Iterator模式可以为遍历不同的聚合结构(需拥有相同的基类)提供一个统一的接口,即支持多态迭代。
然而在实际的引用使用迭代器复写指针以完成stl接口要求是非常繁琐与复杂的.大家见仁见智吧