2010-02-03 48 views
3

我基本上是想有一個容器基類可以返回一個可用於遍歷容器類的一個實例,一個通用的迭代實現通用操作,而無需指定迭代器模板。我想我不能在類模板上實現基礎容器,然後需要基於事先未知的模板類的遍歷算法。基本容器可以使用任何(自定義或標準)容器類型/實現來繼承和實現。這裏有一些代碼示例,以明確:使用迭代器隱藏內部容器並在基礎容器

struct MyObject { 
    int myInt; 
} 

// an abstract container 
class BaseContainer { 
public: 
    virtual void insertMyObject(MyObject& obj) = 0; 
    virtual iterator getFirst(); // the iterator type is for demonstration purposes only 
    virtual iterator getLast(); // the iterator type is for demonstration purposes only 
} 

// Sample container class that uses a std::vector instance to manage objects 
class BaseContainer_Vector : public BaseContainer { 
public: 
    void insertMyObject(MyObject& obj); // e.g. just pushes back to the vector 
    iterator getFirst(); // needs to override the iterator? 
    iterator getLast(); // needs to override the iterator? 
private: 
    std::vector<MyObject> objectContainer; 
} 

我會再有容器對象的列表,我想通過遍歷這兩個容器和存儲的對象。

std::vector<MyContainer*> containers; 
for(int i=0 ; i<containers.size() ; i++){ 
    iterator i = containers[i]->getFirst(); 
    iterator iend = containers[i]->getLast(); 
    for(; i != iend ; i++) { 
    std::cout << (*i).myInt << std::endl; 
    } 
} 

我還想支持boost foreach宏語句。只要range_begin和range_end函數正確,它就支持擴展。但是,boost文檔中的例子使用std :: string :: iterator作爲返回類型,而我需要的是一個泛型迭代器類,我還無法弄清楚如何做到這一點。

std::vector<MyContainer*> containers; 
for(int i=0 ; i<containers.size() ; i++){ 
    BOOST_FOREACH(MyObject obj, *(containers[i])) { 
    std::cout << obj.myInt << std::endl; 
    } 
} 

我想我可以定義自己的迭代器類,然後擴展BaseContainer應該定義延伸的基本迭代器自身的迭代器的每個類。然而,我寧願使用標準迭代器(stl或boost)來支持這種結構,而不是寫自己的迭代器。我想這種方法會起作用,但我很樂意就其效率發表評論。

是否有能夠完美地解決這個問題,一個可行的辦法?還是我錯過了一個簡單的點,可以解決這個問題沒有任何痛苦?

類似的問題可以發現here,但提出的解決方案似乎有點複雜,我的需要,並要求儘可能我能理解不同。

+1

你正在處理的實際用例是什麼?你真的需要兩個動態選擇的容器版本,或者可以推動編譯時間? – 2010-02-03 12:35:41

+0

我不確定它是否能很好地與STL配合工作並提升。那些通常假定迭代器是簡單的值類型;如果你打算使用多態設計,值類型將不可用。 – visitor 2010-02-03 13:49:51

+0

我正在開發的庫需要讓用戶定義自己的容器並將它們註冊到系統中。系統遍歷所有註冊的容器並處理它們,我已經展示了一個使用boost的代碼示例。系統還負責將MyObject類型自動插入到這些容器中。我希望用戶能夠擴展這個容器類,以便他們可以在任何用於管理這些插入對象的結構上應用他們想要的任何順序。 – AdilYalcin 2010-02-03 15:26:19

回答

1

這會變得複雜。

如前所述,首先你需要你的迭代器有值語義,因爲,因爲它們通常是圍繞複製,否則將導致對象切片。

class BaseContainer 
{ 
protected: 
    class BaseIteratorImpl; // Abstract class, for the interface 

public: 
    class iterator 
    { 
    public: 
    iterator(const BaseIteratorImpl& impl); 
    private: 
    BaseIteratorImpl* m_impl; 
    }; 

    iterator begin(); 
    iterator end(); 
}; // BaseContainer 

然後,BaseIterator轉發所有方法m_impl

這樣,您就實現了與多態核心價值的語義語法。

很明顯,你必須處理的深度拷貝語義和妥善銷燬。

一些注意事項:

  • 發佈既是iteratorconst_iterator
  • 名字你的方法emptysizebeginend等等,可以兼容STL算法

你可以檢查SGI Iterators以獲取關於您的操作員應支持的概念和操作以獲得最大兼容性的幫助。

+0

感謝您的迴應,我現在將嘗試基於您的方法實現自定義迭代器。用戶最終需要爲內部使用的容器定義一個自定義增量,開始和結束操作。我會盡快報告結果:) – AdilYalcin 2010-02-03 15:55:37

+0

我繼承了您從std :: iterator 提出的公共迭代器類,所以也可以使它與BOOST_FOREACH一起工作:)感謝您指出正確的方向,它的工作原理就像我希望的那樣,只需很少的代碼開銷:) – AdilYalcin 2010-02-04 13:53:54

+0

對於有興趣的人來說,幫助他們總是很高興......或者至少是我感興趣的問題:) – 2010-02-04 16:20:21