13.5 迭代器
在本章介绍过的示例代码中,迭代器起了很重要的作用,从介绍过的用法看,迭代器类似于指针,用以指示容器中的某个元素。实际上,我们使用的类内迭代器只是迭代器的一种形式,本节将详细介绍迭代器的相关知识。
13.5.1 理解迭代器本质
模板的引入使得函数和类定义脱离了存储类型的限制,在需要时指定它们即可,这是一种泛化的思维观念,这使得算法独立于类型,迭代器是一种更高层次的抽象,其使得算法独立于容器。
迭代器是一种类型,在程序中使用的是其对象。从迭代器的层面上看,对所有类型容器元素的访问应该是等价的,因此,迭代器对象应具备以下功能。
❑间接访问(p)即deference。在迭代器类中必须对一元操作符定义,还需定义运算符->以访问容器元素。
❑迭代器对象之间的赋值,如p=q。在迭代器类中必须定义赋值操作符。
❑迭代器对象间的比较即比较两个迭代器是否相等。因此,在迭代器类内必须对关系运算符==和!=进行定义,原则上讲,不需要对迭代器进行大小比较(<、>)等,就像比较指针实际上是比较其中存储的地址大小一样,这毫无意义。
❑能使用迭代器遍历容器中所有的元素。在本章已给出的示例代码中已经大量应用了诸如“p++”之类的操作,因此,在迭代器类中必须对前缀增1和后缀增1进行定义。
根据上述要求,STL为每个容器类定义了相应的迭代器类,即“Type:iterator”结构,其中,Type是诸如“vector<int>”、“multiset<double>”等形式的模板类,对于某些容器来说,迭代器可能就是指针,如set容器,而对另外一些容器,迭代器可能是对象,如map容器,但不管其内部是如何实现的,类内定义的迭代器都提供了上述基本功能,有的容器根据需要还扩展了一些其他功能。
每个容器类都定义了begin()和end()操作,分别返回指向容器第一个元素和超尾位置的迭代器,每个容器类都定义了++操作,逐个遍历容器中的每个元素。
注意
STL是标准库,因此除非出于研究的需要,一般不需要知道容器类是如何实现的,以及类内迭代器类又是如何实现的,只要会使用即可。
理解迭代器是下一步理解STL算法的基础,正因为有了迭代器,算法才脱离了容器类型的束缚,真正做到了“泛型”和“通用”。