1. 迭代器(iterator)是一中檢查容器內元素並遍歷元素的數據類型。
(1) 每種容器類型都定義了本身的迭代器類型,如vector:
vector<int>::iterator iter;這條語句定義了一個名爲iter的變量,它的數據類型是由vector<int>定義的iterator類型。
(2) 使用迭代器讀取vector中的每個元素:
vector<int> ivec(10,1);
for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();++iter)
{
*iter=2; //使用 * 訪問迭代器所指向的元素
}
const_iterator:
只能讀取容器中的元素,而不能修改。
for(vector<int>::const_iterator citer=ivec.begin();citer!=ivec.end();citer++)
{
cout<<*citer;
//*citer=3; error
}
vector<int>::const_iterator 和 const vector<int>::iterator的區別
const vector<int>::iterator newiter=ivec.begin();
*newiter=11; //能夠修改指向容器的元素
//newiter++; //迭代器自己不能被修改
(3) iterator的算術操做:
iterator除了進行++,--操做,能夠將iter+n,iter-n賦給一個新的iteraor對象。還可使用一個iterator減去另一個iterator.
const vector<int>::iterator newiter=ivec.begin();
vector<int>::iterator newiter2=ivec.end();
cout<<"\n"<<newiter2-newiter;
一個很典型使用vector的STL程式:
1 #include <vector>
2 #include <iostream>
3
4 using namespace std;
5
6 int main() {
7 vector<int> ivec;
8 ivec.push_back(1);
9 ivec.push_back(2);
10 ivec.push_back(3);
11 ivec.push_back(4);
12
13 for(vector<int>::iterator iter = ivec.begin();1. iter != ivec.end(); ++iter)
14 cout << *iter << endl;
15 }
2. Iterator(迭代器)模式
1、概述
Iterator(迭代器)模式又稱Cursor(遊標)模式,用於提供一種方法順序訪問一個聚合對象中各個元素, 而又不需暴露該對象的內部表示。或者這樣說可能更容易理解:Iterator模式是運用於聚合對象的一種模式,經過運用該模式,使得咱們能夠在不知道對象內部表示的狀況下,按照必定順序(由iterator提供的方法)訪問聚合對象中的各個元素。
因爲Iterator模式的以上特性:與聚合對象耦合,在必定程度上限制了它的普遍運用,通常僅用於底層聚合支持類,如STL的list、vector、stack等容器類及ostream_iterator等擴展iterator。
根據STL中的分類,iterator包括:
Input Iterator:只能單步向前迭代元素,不容許修改由該類迭代器引用的元素。
Output Iterator:該類迭代器和Input Iterator極其類似,也只能單步向前迭代元素,不一樣的是該類迭代器對元素只有寫的權力。
Forward Iterator:該類迭代器能夠在一個正確的區間中進行讀寫操做,它擁有Input Iterator的全部特性,和Output Iterator的部分特性,以及單步向前迭代元素的能力。
Bidirectional Iterator:該類迭代器是在Forward Iterator的基礎上提供了單步向後迭代元素的能力。
Random Access Iterator:該類迭代器能完成上面全部迭代器的工做,它本身獨有的特性就是能夠像指針那樣進行算術計算,而不是僅僅只有單步向前或向後迭代。
這五類迭代器的從屬關係,以下圖所示,其中箭頭A→B表示,A是B的強化類型,這也說明了若是一個算法要求B,那麼A也能夠應用於其中。html
input output
\ /
forward
|
bidirectional
|
random access
圖一、五種迭代器之間的關係
vector 和deque提供的是RandomAccessIterator,list提供的是BidirectionalIterator,set和map提供的 iterators是 ForwardIterator,關於STL中iterator迭代器的操做以下:
說明:每種迭代器都可進行包括表中前一種迭代器可進行的操做。
迭代器操做 說明
(1)全部迭代器
p++ 後置自增迭代器
++p 前置自增迭代器
(2)輸入迭代器
*p 復引用迭代器,做爲右值
p=p1 將一個迭代器賦給另外一個迭代器
p==p1 比較迭代器的相等性
p!=p1 比較迭代器的不等性
(3)輸出迭代器
*p 復引用迭代器,做爲左值
p=p1 將一個迭代器賦給另外一個迭代器
(4)正向迭代器
提供輸入輸出迭代器的全部功能
(5)雙向迭代器
--p 前置自減迭代器
p-- 後置自減迭代器
(6)隨機迭代器
p+=i 將迭代器遞增i位
p-=i 將迭代器遞減i位
p+i 在p位加i位後的迭代器
p-i 在p位減i位後的迭代器
p[i] 返回p位元素偏離i位的元素引用
p<p1 若是迭代器p的位置在p1前,返回true,不然返回false
p<=p1 p的位置在p1的前面或同一位置時返回true,不然返回false
p>p1 若是迭代器p的位置在p1後,返回true,不然返回false
p>=p1 p的位置在p1的後面或同一位置時返回true,不然返回false
只有順序容器和關聯容器支持迭代器遍歷,各容器支持的迭代器的類別以下:
容器 支持的迭代器類別 容器 支持的迭代器類別 容器 支持的迭代器類別
vector 隨機訪問 deque 隨機訪問 list 雙向
set 雙向 multiset 雙向 map 雙向
multimap 雙向 stack 不支持 queue 不支持
priority_queue 不支持
2、結構
Iterator模式的結構以下圖所示:ios
圖二、Iterator模式類圖示意
3、應用
Iterator模式有三個重要的做用:
1)它支持以不一樣的方式遍歷一個聚合.複雜的聚合可用多種方式進行遍歷,如二叉樹的遍歷,能夠採用前序、中序或後序遍歷。迭代器模式使得改變遍歷算法變得很容易: 僅需用一個不一樣的迭代器的實例代替原先的實例便可,你也能夠本身定義迭代器的子類以支持新的遍歷,或者能夠在遍歷中增長一些邏輯,若有條件的遍歷等。
2)迭代器簡化了聚合的接口. 有了迭代器的遍歷接口,聚合自己就再也不須要相似的遍歷接口了,這樣就簡化了聚合的接口。
3)在同一個聚合上能夠有多個遍歷 每一個迭代器保持它本身的遍歷狀態,所以你能夠同時進行多個遍歷。
4)此外,Iterator模式能夠爲遍歷不一樣的聚合結構(需擁有相同的基類)提供一個統一的接口,即支持多態迭代。
簡單說來,迭代器模式也是Delegate原則的一個應用,它將對集合進行遍歷的功能封裝成獨立的Iterator,不但簡化了集合的接口,也使得修改、增 加遍歷方式變得簡單。從這一點講,該模式與Bridge模式、Strategy模式有必定的類似性,但Iterator模式所討論的問題與集合密切相關, 形成在Iterator在實現上具備必定的特殊性,具體將在示例部分進行討論。
4、優缺點
正如前面所說,與集合密切相關,限制了 Iterator模式的普遍使用,就我的而言,我不大認同將Iterator做爲模式提出的觀點,但它又確實符合模式「常常出現的特定問題的解決方案」的 特質,以致於我又不得不認可它是個模式。在通常的底層集合支持類中,咱們每每不肯「避輕就重」將集合設計成集合 + Iterator 的形式,而是將遍歷的功能直接交由集合完成,以避免犯了「過分設計」的詬病,可是,若是咱們的集合類確實須要支持多種遍歷方式(僅此一點仍不必定須要考慮 Iterator模式,直接交由集合完成每每更方便),或者,爲了與系統提供或使用的其它機制,如STL算法,保持一致時,Iterator模式才值得考 慮。
5、舉例
能夠考慮使用兩種方式來實現Iterator模式:內嵌類或者友元類。一般迭代類需訪問集合類中的內部數據結構,爲此,可在集合類中設置迭代類爲friend class,但這不利於添加新的迭代類,由於須要修改集合類,添加friend class語句。也能夠在抽象迭代類中定義protected型的存取集合類內部數據的函數,這樣迭代子類就能夠訪問集合類數據了,這種方式比較容易添加新的迭代方式,但這種方式也存在明顯的缺點:這些函數只能用於特定聚合類,而且,不可避免形成代碼更加複雜。
STL的list::iterator、deque::iterator、rbtree::iterator等採用的都是外部Iterator類的形式,雖然STL的集合類的iterator分散在各個集合類中,但因爲各Iterator類具備相同的基類,保持了相同的對外的接口(包括一些traits及tags等,感興趣者請認真閱讀參考一、2),從而使得它們看起來仍然像一個總體,同時也使得應用algorithm成爲可能。咱們若是要擴展STL的iterator,也須要注意這一點,不然,咱們擴展的iterator將可能沒法應用於各algorithm。
如下是一個遍歷二叉樹的Iterator的例子,爲了方便支持多種遍歷方式,並便於遍歷方式的擴展,其中還使用了Strategy模式(見筆記21):
(注:一、雖然下面這個示例是本系列全部示例中花費我時間最多的一個,但我不得不認可,它很是不完善,感興趣的朋友,能夠考慮參考下面的參考材料將其補充完善,或提出寶貴改進意見。二、 我本想考慮將其封裝成與STL風格一致的形式,使得咱們遍歷二叉樹必須經過Iterator來進行,但因爲二叉樹在結構上較線性存儲結構複雜,使訪問必須 經過Iterator來進行,但這不可避免使得BinaryTree的訪問變得異常麻煩,在具體應用中還須要認真考慮。三、如下只提供了Inorder<中序>遍歷iterator的實現。)算法
http://www.cnblogs.com/yc_sunniwell/archive/2010/06/25/1764934.html數據結構