2010-04-16 64 views
12

我目前正在嘗試理解各種語言中迭代器的內在性,即它們實現的方式。在C++中編寫我自己的stl-like迭代器實現

例如,有以下類暴露列表界面。

template<class T> 
class List 
{ 

    public: 

    virtual void Insert(int beforeIndex, const T item) throw(ListException) =0 ; 
    virtual void Append(const T item) =0; 

    virtual T Get(int position) const throw(ListException) =0; 
    virtual int GetLength() const =0; 

    virtual void Remove(int position) throw(ListException) =0; 


    virtual ~List() =0 {}; 
}; 

根據四人幫,實現能夠支持不同類型的遍歷的迭代器的最佳方式是創建基本的迭代器類(列表的朋友)與可訪問列表的成員保護的方法。 Iterator的具體實現將以不同的方式處理作業,並通過基本接口訪問List的私有和受保護數據。

從這裏開始,事情變得混亂。說,我有類LinkedList和ArrayList,都從List派生,並且還有相應的迭代器,每個類都返回。我怎樣才能實現LinkedListIterator?我完全沒有想法。基類迭代器類可以從列表中檢索什麼樣的數據(這是一個純粹的接口,而所有派生類的實現差別很大)?

+3

Boost迭代器庫是一個很好的信息來源,並且開發了新的迭代器類型/特性http://www.boost.org/doc/libs/1_42_0/libs/iterator/doc/index.html – Hippicoder 2010-04-16 22:26:32

+1

這種氣味如Java/C#代碼。通常,好的C++看起來不像Java或C#。 – 2010-04-16 22:51:39

+0

爲什麼你想從'List'派生,如果它是模板化的?如果刪除所有'虛擬'限定符並提供缺少的定義,則可以將其用於任何可想到的目的。 – wilhelmtell 2010-04-17 02:27:31

回答

14

STL並沒有真正使用抽象基類和虛函數。相反,它被有意設計成不是OO(在GoF意義上)並且完全基於模板,旨在「編譯時多態性」。模板不關心抽象接口。只要它們具有足夠類似的接口(例如,如果您打電話給Appendpush_back而不是更多的代碼,期望符合STL的容器可以爲您工作,如std::back_insert_iterator)。

一個兼容STL的迭代器將不得不超負荷很多運營商的表現就像一個指針(儘可能,考慮到容器的限制),包括*->++--(如果雙向 - 雙鏈接), ==!=

+2

並注意'++'和'--'分別是兩個不同的運算符。如果你正在實現的迭代器類型需要一個'++',那麼它們都是,而'--'也是一樣的。 – 2010-04-16 23:04:08

7

C++標準庫在迭代器的實現中不使用多態和繼承;相反,它使用C++模板元編程和「概念」的概念(但不是形式語法*)。

從本質上講,如果您的迭代器類的接口符合一些要求,它將會工作。這套要求被稱爲「概念」。有幾種不同的迭代器概念(參見this page for a list of all of them),它們是分層的。創建一個兼容的C++迭代器的基礎是讓你的接口符合這個概念。對於一個簡單的迭代器,也僅限於前進方向,這將需要:

  • 一種從提領你的迭代所得的值的typedef value_type
  • A typedef reference_type,它是相應值類型的參考類型。
  • A typedef pointer,它是相應值類型的指針類型。
  • typedef iterator_category,根據您的遍歷機制,它需要是input_iterator_tag,forward_iterator_tag,bidirectional_iterator_tag或random_access_iterator_tag之一。
  • A typedef difference_type指示減去兩個不同迭代器的結果。
  • A const value_type& operator*()const取消引用迭代器的函數。
  • A value_type& operator*()函數,如果你的迭代器可以用來操縱值。
  • 遞增(operator++()operator++(int)功能)尋求前進。
  • 的不同功能:difference_type operator-(const type_of_iterator&)

如果你選擇了更先進的迭代器類別之一,你可能還需要以指定遞減,並且加上運營商能夠尋求向後或尋求的任意距離。

* C++標準庫以非正式方式頻繁使用概念,C++標準委員會試圖引入一種用C++聲明它們的正式機制(目前它們只存在於標準庫的文檔中,而不存在於任何顯式代碼)。然而,對於該提案的持續不同意見導致其被C++ 0x取消,不過之後它很可能會重新考慮該標準。

+2

typedefs不是迭代器類型的要求,但是'iterator_traits'的合適的特殊性是。使用'iterator'模板和一個迭代器類型標記來安排這種智能的方法,而不是通過顯式定義typedef。另外,前向迭代器不需要'operator-',(直到RandomAccess才需要),但是需要'=='和'!='表達式。迭代器不需要'reference_type'和'pointer',但默認的'iterator_traits'模板需要它們。我不知道這是爲什麼。 – 2010-04-16 23:16:30

+0

@Steve:C++ 0x確實需要'reference'和'pointer'。 – Potatoswatter 2010-04-17 05:39:17

+0

@Steve,這是正確的......它確實說在我鏈接的文檔中,但我想保持簡單;換句話說,我的指示是足夠的,但不是必要的。 – 2010-04-18 01:37:46