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

相關文章
相關標籤/搜索