STL源码分析-iterator(迭代器)

1. GOF 迭代器设计模式算法

前面一篇文章有写到stl_list的实现,也实现了一下相应的iterator,可是后面以为,实现具体容器以前有必要介绍一下iterator(迭代器) 。那么迭代器是什么呢?编程

GOF的设计模式是这样定义的: 提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。设计模式

大概意思是,例如一个聚合对象(list),咱们该如何来访问它的元素,而又不暴露内部结构;并且还要针对不一样的须要,可能以不一样的方式遍历这个list;那么即便,咱们知道大概会有哪些遍历操做,那咱们也不会但愿list接口中充斥着各类不一样遍历操做。一句话,就是若是把遍历和操做元素的各类方法都放到list中来实现,那么将会致使list类中结构变得混乱并且不稳定。函数

正好迭代器就是用来提供给外部访问聚合对象元素的一个结构。 那GOF设计模式,采用的实现方式是OOP(面向对象),类图关系以下:spa

具体的聚合对象有本身的继承关系,具体的iterator也有本身的继承关系,也就是经过继承多态来实现用户侧代码无需修改,就能够兼容不一样的聚合对象。在GOF设计模式书中专门有一点提到:使用多态迭代器是有代价的。他们要求用一个Factory Method动态分配迭代器对象。所以仅当必须多态时才使用它们设计

2. STL 迭代器指针

在C++ STL中,也是继承了GOF提出的迭代器基本需求,而且迭代器(iterator)扮演着重要角色,来将将容器和算法分开,彼此独立设计,最后再以胶着剂(iterator)将它们撮合在一块儿。对象

那么C++ STL实现iterator和GOF介绍的迭代器实现方法什么区别呢? 那首先咱们须要了解C++中的两个编程范式的概念,GP(泛型编程)和OOP(面向对象编程)。blog

在C++语言里面,咱们能够如下方式来简单区分一下GP和OOP:继承

GP: 泛型编程,也被称为"静态多态",多种数据类型在同一种算法或者结构上皆可操做,其效率与针对某特定数据类型而设计的算法或者结构相同, 具体数据类型在编译期肯定,编译器承担更多,代码执行效率高。在STL中利用GP将methods和datas实现了分而治之。

OOP: 将methods和datas关联到一块儿 (通俗点就是方法和成员变量放到一个类中实现),经过继承的方式,利用虚函数表(virtual)实现运行时类型断定,也叫"动态多态", 因为运行过程当中需根据类型去检索虚函数表,所以效率相对较低。

恰好,C++ STL库的整个实现采用的就是GP(Generic Programming),而不是OOP(Object Oriented Programming)。而GOF设计模式采用的 就是继承关系实现的,所以,相对来说,C++ STL的实现效率会相对较高,并且也更有利于维护。

3. STL iterator分类和总结

迭代器类型基本关系:

STL 迭代器基本介绍:

一、输入迭代器:只读,一次传递

可为输入迭代器预约义实现只有istream_iterator和istreambuf_iterator,用于从一个输入流istream中读取。一个输入迭代器仅能对它所选择的每一个元素进行一次解析,它们只能向前移动。一个专门的构造函数定义了超越末尾的值。老是,输入迭代器能够对读操做的结果进行解析(对每一个值仅解析一次),而后向前移动。

二、输出迭代器:只写,一次传递

这是对输入迭代器的补充,不过是写操做而不是读操做。为输出迭代器的预约义实现只有ostream_iterator和ostreambuf_iterator,用于向一个输出流ostream写数据,还有一个通常较少使用的raw_storage_iterator。他们只能对每一个写出的值进行一次解析,而且只能向前移动。对于输出迭代器来讲,没有使用超越末尾的值来结束的概念。总之,输出迭代器能够对写操做的值进行解析(对每个值仅解析一次),而后向前移动。

三、前向迭代器:屡次读/写

前向迭代器包含了输入和输出迭代器二者的功能,加上还能够屡次解析一个迭代器指定的位置,所以能够对一个值进行屡次读/写。顾名思义,前向迭代器只能向前移动。没有为前向迭代器预约义迭代器。

四、双向迭代器:operator--

双向迭代器具备前向迭代器的所有功能。另外它还能够利用自减操做符operator--向后一次移动一个位置。由list容器中返回的迭代器都是双向的。

五、随机访问迭代器:相似于一个指针

随机访问迭代器具备双向迭代器的全部功能,再加上一个指针全部的功能(一个指针就是一个随机访问迭代器),除了没有一种“空(null)”迭代器和空指针对应。基本上能够这样说,一个随机访问迭代器就像一个指针那样能够进行任何操做,包括使用操做符operator[]进行索引,加某个数值到一个指针就能够向前或者向后移动若干个位置,或者使用比较运算符在迭代器之间进行比较。

能够参考一下以前list实现的iterator代码,iterator内部维护一个list节点指针,而后对++和--进行操做符重载时,实际上是指针的先后移动,所以stl_list的迭代器类型为双向迭代器。

![](https://img2018.cnblogs.com/blog/1285081/201809/1285081-20180925233604703-939646533.png)

迭代器做为STL的一个重要组成部分,今天算是作了一个简单的总结,在后续分析STL其余内容的过程当中也会常常遇到!

2018年9月25日23:44:02

相关文章
相关标签/搜索