標準C++中的Iterator(迭代器)

來源:互聯網
上載者:User

一、概述
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:該類迭代器能完成上面所有迭代器的工作,它自己專屬的特性就是可以像指標那樣進行算術計算,而不是僅僅只有單步向前或向後迭代。
vector 和deque提供的是RandomAccessIterator,list提供的是BidirectionalIterator,set和map提供的 iterators是 ForwardIterator,關於STL中iterator的更多資訊。

二、應用
Iterator模式有三個重要的作用:
1)它支援以不同的方式遍曆一個彙總 複雜的彙總可用多種方式進行遍曆,如二叉樹的遍曆,可以採用前序、中序或後序遍曆。迭代器模式使得改變遍曆演算法變得很容易: 僅需用一個不同的迭代器的執行個體代替原先的執行個體即可,你也可以自己定義迭代器的子類以支援新的遍曆,或者可以在遍曆中增加一些邏輯,如有條件的遍曆等。
2)迭代器簡化了彙總的介面 有了迭代器的遍曆介面,彙總本身就不再需要類似的遍曆介面了,這樣就簡化了彙總的介面。
3)在同一個彙總上可以有多個遍曆 每個迭代器保持它自己的遍曆狀態,因此你可以同時進行多個遍曆。
4)此外,Iterator模式可以為遍曆不同的彙總結構(需擁有相同的基類)提供一個統一的介面,即支援多態迭代。
簡 單說來,迭代器模式也是Delegate原則的一個應用,它將對集合進行遍曆的功能封裝成獨立的Iterator,不但簡化了集合的介面,也使得修改、增 加遍曆方式變得簡單。從這一點講,該模式與Bridge模式、Strategy模式有一定的相似性,但Iterator模式所討論的問題與集合密切相關, 造成在Iterator在實現上具有一定的特殊性,具體將在樣本部分進行討論。

三、優缺點
正如前面所說,與集合密切相關,限制了 Iterator模式的廣泛使用,就個人而言,我不大認同將Iterator作為模式提出的觀點,但它又確實符合模式“經常出現的特定問題的解決方案”的 特質,以至於我又不得不承認它是個模式。在一般的底層集合支援類中,我們往往不願“避輕就重”將集合設計成集合 + Iterator 的形式,而是將遍曆的功能直接交由集合完成,以免犯了“過度設計”的詬病,但是,如果我們的集合類確實需要支援多種遍曆方式(僅此一點仍不一定需要考慮 Iterator模式,直接交由集合完成往往更方便),或者,為了與系統提供或使用的其它機制,如STL演算法,保持一致時,Iterator模式才值得考 慮。

四、舉例
可以考慮使用兩種方式來實現Iterator模式:內嵌類或者友元類。通常迭代類需訪問集合類中的內部資料結構,為此,可在集合類中設定迭代類為friend class,但這不利於添加新的迭代類,因為需要修改集合類,添加friend class語句。也可以在抽象迭代類中定義protected型的存取集合類內部資料的函數,這樣迭代子類就可以訪問集合類資料了,這種方式比較容易添加新的迭代方式,但這種方式也存在明顯的缺點:這些函數只能用於特定彙總類,並且,不可避免造成代碼更加複雜。

STL的list::iterator、deque::iterator、rbtree::iterator等採用的都是外部Iterator類的形式,雖然STL的集合類的iterator分散在各個集合類中,但由於各Iterator類具有相同的基類,保持了相同的對外的介面(包括一些traits及tags等,感興趣者請認真閱讀參考1、2),從而使得它們看起來仍然像一個整體,同時也使得應用algorithm成為可能。我們如果要擴充STL的iterator,也需要注意這一點,否則,我們擴充的iterator將可能無法應用於各algorithm。

五、代碼

#include <assert.h>

#include <iostream>
#include <xutility>
#include <iterator>
#include <algorithm>
using namespace std;

template <typename T>
class BinaryTree;
template <typename T>
class Iterator;

template <typename T>
class BinaryTreeNode
{

public:
     typedef BinaryTreeNode<T> NODE;
     typedef BinaryTreeNode<T>* NODE_PTR;

     BinaryTreeNode(const T& element) : data(element), leftChild(NULL), rightChild(NULL), parent(NULL) { }
     BinaryTreeNode(const T& element, NODE_PTR leftChild, NODE_PTR rightChild)
         :
data(element), leftChild(leftChild), rightChild(rightChild), parent(NULL)
     {

         if (leftChild)
             leftChild->setParent(this);
         if (rightChild)
             rightChild->setParent(this);
     }

    
     T getData(void) const { return data; }
     NODE_PTR getLeft(void) const { return leftChild; }
     NODE_PTR getRight(void) const { return rightChild; }
     NODE_PTR getParent(void) const { return parent; }
     void SetData(const T& data) { this->data = item; }
     void setLeft(NODE_PTR ptr) { leftChild = ptr; ptr->setParent(this); }
     void setRight(NODE_PTR ptr) { rightChild = ptr; ptr->setParent(this); }
     void setParent(NODE_PTR ptr) { parent = ptr; }
private:
     T data;
     NODE_PTR leftChild;
     NODE_PTR rightChild;
     NODE_PTR parent;   // pointer to parent node, needed by iterator

     friend class BinaryTree<T>;
};

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.