STL 源碼分析 # stl_iterator & stl_iterator_base #

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 : )





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章