STL 源码分析 # stl_iterator_base && stl_iterator #
这里能很清楚的看到各个基础类型的继承关系
template <class _Tp, class _Distance> struct input_iterator { typedef input_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; struct output_iterator { typedef output_iterator_tag iterator_category; typedef void value_type; typedef void difference_type; typedef void pointer; typedef void reference; }; template <class _Tp, class _Distance> struct forward_iterator { typedef forward_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; template <class _Tp, class _Distance> struct bidirectional_iterator { typedef bidirectional_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; }; template <class _Tp, class _Distance> struct random_access_iterator { typedef random_access_iterator_tag iterator_category; typedef _Tp value_type; typedef _Distance difference_type; typedef _Tp* pointer; typedef _Tp& reference; };
五个类的实现中都有
- iterator_category 集中迭代器策略.
- value_type 所谓的value_type是指迭代器所知对象的型别.任何一个打算与STL完美搭配的class 都应 该定义自己的value_type
- difference_type 用来表示两个迭代器之间的距离,因此他也可以用来表示一个容器的最大容量.因为对于连续 空间的容器而言,头尾之间的距离就是其最大容量.如果一个泛型算法提供计数功能,例如 STL的count(),其返回值就必须是迭代器difference type
- pointer 指针啦..
- reference 在C++中, 函数如果要传回左值, 都是以by reference的方式进行, 所以当p是一个mutable iterators时, 如果其value_type是T, 那么*p的型别不应该是T, 而应该是T&.
五个成员.
对于迭代器的策略,又有五种:
input iterator: 这种迭代器所知的对象不允许外界改变. read only
output iterator: write only
forward iterator: 允许写入型算法在此迭代器所形成的区间上进行读写操作.
bidirectional iterator: 可双向移动的迭代器.
random access iterator: 前面四种迭代器都只供应一部分指针运算能力(前三种只支持++, 第四种开始支持--,). 这里第五种random access iterator支持所有指针算术能力. p +n, p -n, p[n], p1- p2, p1 < p2
这里你能看到__advance 函数被各种重载. 五种迭代器里面, 四种都有相应的版本, 但是就是没有对于forward iterator的版本,
关于back_insert_iterator迭代器的实现: 在我看来,其实就是对于一个container指针的封装.
这个指针实质上指向对应的class 类型(_Container). 而对这个迭代器赋值, 实质上就是把value 通过调用push_back()函数置于最后.
back_inserter函数的实现:
类似的, 有前向插入迭代器 front_insert_iterator
front_inserter()函数的实现.
后面迭代器类似这种构造方式的不再赘述.
比较两个迭代器相等实质上还是比较迭代器类所维护的指针是否相等.
下面的迭代器会调用base()返回他们维护的指向对象的指针.
你会发现前面的各种insert迭代器都是维护的一个指针, 但是到了各种reverse iterator的时候好像就是维护的一个具体的对象了.看下面:
这就是细节. 其实这里各种reverse iterator本质上还是维护的指针, 为什么呢? 他们间接的维护一个前向的迭代器,只是改变这个前向迭代器的运算方式而已!!
所以, 他这里表现出的具体的维护的是一个迭代器了, 而不是指针!
下面看看 IO 流迭代器istream_iterator 和ostream_iterator
下面几乎就是一个istream_iterator的全貌.
这个类最核心的任务也就是维护他那三个私有成员
_M_stream
_M_value
_M_ok
默认的构造函数会把_M_stream(一个指针)初始化为0, 而bool值 _M_ok为false
_M_read()当 _M_stream指针非空的时候才可以从 _M_stream指向的地址处读取一个值, 并把值存放在 _M_value.
下面是输出迭代器 ostream_iterator的实现.
整个类就是为了维护好 _M_stream 和 _M_string两个私有成员,
就这些, 其他细节不再赘述, RTFSC : )