2017-09-12 65 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 
    } 
}