迭代器模式

31次阅读

共计 1649 个字符,预计需要花费 5 分钟才能阅读完成。

简介

迭代器模式,提供一种方法访问聚合对象中的各个元素,而不需要暴露它的内部实现。迭代器模式在 stl 的容器中被普遍使用,实际开发中自己实现一个迭代器并不多见,使用居多。

UML 类图

示例

以数组为例,来说明实现迭代器模式,使用了模板类,可以实例化多种类型的数组。
迭代器和聚合对象相关类,iterator.h

#ifndef ITERATOR_H
#define ITERATOR_H

const int nSize = 10;
template <class T> class CAggregate;

template<class T>
class CIterator
{
public:
    CIterator(){m_nIndex = 0;}
    virtual void First() = 0;
    virtual void Next() = 0;
    virtual bool HasNext() = 0;
    virtual T GetCurrentItem() = 0;
protected:
    int m_nIndex;
};
template<class T>
class CConcreteIterator:public CIterator<T>
{
public:
    CConcreteIterator(CAggregate<T>* pAggregate)
    {m_pAggregate = pAggregate;}
    void First()
    {m_nIndex = 0;}
    void Next()
    {++m_nIndex;}
    bool HasNext()
    {if(m_nIndex < nSize && m_nIndex >= 0)
            return true;
        return false;
    }
    T GetCurrentItem()
    {return m_pAggregate->GetItem(m_nIndex);
    }
private:
    CAggregate<T>* m_pAggregate; 
};
template <class T>
class CAggregate
{
public:
    CAggregate(){m_nCurIndex = 0;}
    virtual CIterator<T>* CreateIterator() = 0;
    virtual T GetItem(const int nIndex) = 0;
    virtual void Add(T t) = 0;
protected:
    T m_arralist[nSize];
    int m_nCurIndex;
};

template <class T>
class CConcreteAggregate:public CAggregate<T>
{
public:
    CConcreteAggregate(){}
    CIterator<T>* CreateIterator()
    {return new CConcreteIterator<T>(this);
    }
    T GetItem(const int nIndex)
    {return m_arralist[nIndex];
    }
    void Add(T t)
    {m_arralist[m_nCurIndex] = t;
        ++m_nCurIndex;
    }
};
#endif

客户端调用,main.cpp

#include <iostream>
#include "iterator.h"

using namespace std;
#define SAFE_DELETE(p) if(p){delete (p); (p) = NULL;}
int main(int argc, char* argv[])
{
    CAggregate<int>* pAggregate = new CConcreteAggregate<int>;
    for(int i = 0; i < nSize; ++ i)
    {pAggregate->Add(i);
    }

    CIterator<int>* pIter = pAggregate->CreateIterator();
    for(; pIter->HasNext() ;)
    {cout<<pIter->GetCurrentItem()<<endl;
        pIter->Next();}
    SAFE_DELETE(pIter);
    SAFE_DELETE(pAggregate);
     return 0;
}

正文完
 0

迭代器模式

31次阅读

共计 1117 个字符,预计需要花费 3 分钟才能阅读完成。

实现一个内部迭代器

    function each(arr,fn){for(let i =0; i<arr.length; i++){fn(i,arr[i])
      }
    }
    each([1,2,3],function(i,n){console.log(i) //0 1 2
      console.log(n)// 1 2 3
    })

可以看出内部迭代器在调用的时候非常简单, 使用者不用关心迭代器内部实现的细节, 但这也是内部迭代器的缺点。比如要比较两数组是否相等, 只能在其回调函数中作文章了, 代码如下:

    function each(arr, fn) {for (let i = 0; i < arr.length; i++) {fn(i, arr[i])
      }
    }
    const compare = function (arr1, arr2) {
      var isTrue = 1
      each(arr1, function (i, n) {if (arr2[i] !== n) {console.log('两数组不相等')
          isTrue = 2
          return
        }
      })
      if (isTrue == 1) {console.log('两数组相等')
      }

    }
    const arr1 = [1, 2, 3]
    const arr2 = [1, 2, 4]
    compare(arr1, arr2)// 两数组不相等 

实现一个外部迭代器

相较于内部迭代器, 外部迭代器将遍历的权利转移到外部, 因此在调用的时候拥有了更多的自由性, 不过缺点是调用方式较复杂。

  const iterator = function(arr){
      let current = 0
      const next = function(){current = current + 1}
      const done = function(){return current >= arr.length}
      const value = function(){return arr[current]
      }
      return {
        next,
        done,
        value
      }
    }
    const arr1 = [1,2,3]
    const arr2 = [1,2,3]
    const iterator1 = iterator(arr1)
    const iterator2 = iterator(arr2)
    const compare = function(iterator1,iterator2){while(!iterator1.done()&&!iterator2.done()){if(iterator1.value() !== iterator2.value()){console.log('两数组不等')
          return
        }
        iterator1.next()  // 外部迭代器将遍历的权利转移到外部
        iterator2.next()}
      console.log("两数组相等")
    }
    compare(iterator1,iterator2) // 两数组相等 

正文完
 0