2017-09-12 63 views
0

我正在C++中設計一個接口(抽象類),它實現了一種樹結構:每個實例都有零個,一個或多個子元素。孩子們也是界面的實例。提供訪問抽象類的集合

我通常把一些想法放在一個接口中,以排除特定的實現。例如,方法不應該返回引用,因爲這會迫使實現將值存儲在某處。這會排除重新計算每次調用值的實現;或者以某種方式轉換返回值的包裝。

但是,使用此界面,我不確定如何提供訪問實例的子項的最佳方法。到目前爲止,我想出了兩個選項:

class Interface 
{ 
public: 

    virtual ~Interface() = default; 

    // IDEA 1: return a collection of references. 
    virtual auto getChildren() const -> std::vector<std::reference_wrapper<Interface>> = 0; 

    // IDEA 2: accept a visitor. 
    virtual void visitChildren(const std::function<void(Interface&)> &visitor) const = 0; 

}; 

我的問題:什麼是最好的方式*提供訪問抽象類的集合。其他想法和方法非常讚賞(例如,如果可能的話,基於迭代器的方法)。

*任何或所有以下屬性:最地道,最靈活,最具擴展性,最易維護,最直觀,語義最強,...

+3

你有沒有聽說過的迭代器:

class Interface { class iterator_impl { virtual ~iterator_impl() = default; // Fill the rest }; public: class iterator { std::unique_ptr<iterator_impl> _impl; iterator(std::unique_ptr<iterator_impl> impl) : _impl(std::move(impl)) {} public: Iterface& operator*() { //forward to _impl } }; virtual iterator begin() = 0; virtual iterator end() = 0; }; 

提供完整的迭代器協議之後,Interface&可以在地道的C++代碼中使用?這在C++中佔據主導地位。只要看看標準庫。 – StoryTeller

+0

@StoryTeller您能否提供一個我如何在這裏使用迭代器的例子(考慮'begin'和'end'函數也需要是純虛擬的)?或者我是以錯誤的方式思考迭代器方法? –

+0

認爲協變式返回類型(有點)。您將返回一個抽象迭代器的句柄。當然,開始和結束必須是虛擬的。 – StoryTeller

回答

1

配售的設計過於類似Java的一邊討論。如果你想接近地道的C++,去迭代器:

void foo(Interface& interface) { 
    for(auto& i : interface) { 
    //Do stuff 
    } 
}