在C ++中编写我自己的类似stl的Iterator实现

时间:2010-04-16 22:04:56

标签: c++ design-patterns iterator

我目前正在尝试理解各种语言的迭代器的内在函数,即它们的实现方式。

例如,有以下类公开列表界面。

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 {};
};

根据 GoF ,实现可以支持不同类型遍历的迭代器的最佳方法是使用可以访问List成员的受保护方法创建基类Iterator类(List的朋友)。 Iterator的具体实现将以不同的方式处理作业,并通过基接口访问List的私有和受保护数据。

从这里开始,事情变得令人困惑。说,我有类LinkedList和ArrayList,都是从List派生的,并且还有相应的迭代器,每个类都返回。我该如何实现LinkedListIterator?我完全没有想法。基础迭代器类可以从List中检索哪种数据(这只是一个接口,而所有派生类的实现差异很大)?

2 个答案:

答案 0 :(得分:14)

STL并没有真正使用抽象基类和虚函数。相反,它被明智地设计为不是OO(在GoF意义上)并且完全基于模板构建,旨在“编译时多态性”。模板不关心抽象接口。只要它们具有足够相似的界面(例如,如果您要调用Append push_back,那么事情就会起作用,更多代码期望符合STL的容器对您有用,例如std::back_insert_iterator)。

符合STL标准的迭代器必须使许多运算符超载,使其表现得像指针(尽可能,考虑到容器的限制),包括*->,{{1} },++(如果双向 - 双重关联),--==

答案 1 :(得分:7)

C ++标准库在迭代器的实现中不使用多态和继承;相反,它使用C ++模板元编程和“概念”的概念(但不是形式语法*)。

基本上,如果迭代器类的接口遵循某些要求,它将起作用。这组要求称为“概念”。有几种不同的迭代器概念(参见this page for a list of all of them),它们是分层的。创建兼容的C ++迭代器的基础是使您的接口符合该概念。对于仅向前移动的简单迭代器,这需要:

  • typedef value_type,用于取消引用迭代器所产生的值。
  • typedef reference_type,它是相应值类型的引用类型。
  • typedef pointer,它是相应值类型的指针类型。
  • typedef iterator_category,需要是input_iterator_tag,forward_iterator_tag,bidirectional_iterator_tag或random_access_iterator_tag之一,具体取决于您的遍历机制。
  • typedef difference_type,指示减去两个不同迭代器的结果。
  • 用于解除引用迭代器的const value_type& operator*()const函数。
  • 如果您的迭代器可用于操纵值,则为value_type& operator*()函数。
  • 增加(operator++()operator++(int)函数)以寻求前瞻。
  • 差异函数:difference_type operator-(const type_of_iterator&)

如果您选择一个更高级的迭代器类别,您可能还需要指定一个减量和加号运算符,以便能够向后搜索或寻找任意距离。

* C ++标准库以非正式的方式经常使用概念,C ++标准委员会试图引入一种在C ++中声明它们的正式机制(目前它们只存在于标准库的文档中,而不是任何显式的码)。但是,对该提案的持续不同意见导致它被废弃为C ++ 0x,尽管之后很可能会重新考虑该标准。