正在加载……
专注、离线、切勿分心
常见设计模式的解析和实现(C++)之十八-Iterator 模式  
作用:
提供一种方法顺序访问一个聚合对象中各个元素,,而又不需暴露该对象的内部表示.  

   Iterator 几乎是大部分人在初学 C++的时候就无意之中接触到的第一种设计模式,因为在 STL 之中,所有的容器类都有与之相关的迭代器.以前初学 STL 的时候,时常在看到讲述迭代器作用的时候是这么说的:提供一种方式,使得算法和容器可以独立的变化,而且在访问容器对象的时候不必暴露容器的内部细节,具体是怎么做到这一点的呢?在 STL 的实现中,所有的迭代器(Iterator)都必须遵照一套规范,这套规范里面定义了几种类型的名称,比如对象的名称,指向对象的指针的名称,指向对象的引用的名称....等等,当新生成一个容器的时候与之对应的 Iterator 都要遵守这个规范里面所定义的名称,这样在外部看来虽然里面的实现细节不一样,但是作用(也就是对外的表象)都是一样的,通过某个名称可以得到容器包含的对象,通过某个名称可以得到容器包含的对象的指针等等的.而且,采用这个模式把访问容器的重任都交给了具体的 iterator 类中.于是,在使用 Iterator 来访问容器对象的算法不需要知道需要处理的是什么容器,只需要遵守事先约定好的 Iterator 的规范就可以了;而对于各个容器类而言,不管内部的事先如何,是树还是链表还是数组,只需要对外的接口也遵守 Iterator 的标准,这样算法(Iterator 的使用者)和容器(Iterator 的提供者)就能很好的进行合作,而且不必关心对方是如何事先的,简而言之,Iterator 就是算法和容器之间的一座桥梁.
   在下面的实现中,抽象基类 Iterator 可以看做是前面提到的 Iterator 的规范,它提供了所有 Iterator 需要遵守的规范也就是对外的接口,而它的派生类 ConcreateIterator 则是 ConcreateAggregate 容器的迭代器,它遵照这个规范对容器进行迭代和访问操作。
#ifndef __ITERATOR_H__
#define __ITERATOR_H__
#include<iostream>
using namespace std;
typedef int Data;
class Iterator;
class Aggregate
{
        public:
                Aggregate();
                virtual Iterator* createIterator() = 0;
                virtual int size() = 0;
                virtual Data& getItem(int idx) = 0;
                virtual Iterator* begin() = 0;
                virtual Iterator* end() = 0;
                virtual ~Aggregate();
};
class ConcreteAggregate:public Aggregate
{
        public:
                ConcreteAggregate(int);
                ~ConcreteAggregate();
                Iterator* createIterator();
                int size();
                Data& getItem(int idx);
                Iterator* begin();
                Iterator* end();
        private:
                int _size;
                Data* _pData;
};
class Iterator
{
        public:
                virtual void first() = 0;
                virtual void next() = 0;
                virtual bool isDone() = 0;
                virtual Data& currentItem() = 0;
                virtual bool operator!=(Iterator&) = 0;
                virtual Data& operator*() = 0;
                virtual void operator++() = 0;
                virtual int index() = 0;
                virtual ~Iterator() ;
};
class ConcreteIterator:public Iterator
{
        public:
                ConcreteIterator(Aggregate*,int);
                void first();
                void next();
                bool isDone();
                Data& currentItem();
                bool operator!=(Iterator&);
                Data& operator*();
                void operator++();
                int index();
                ~ConcreteIterator();
        private:
                Aggregate* _pAggregate;
                int _idx;
};
#endif
#include<iostream>
#include"iterator.h"
using namespace std;
Aggregate::Aggregate()
{
        cout<<"Aggregate()"<<endl;
}
Aggregate::~Aggregate()
{
        cout<<"~Aggregate()"<<endl;
}
ConcreteAggregate::ConcreteAggregate(int size):_size(size)
{
        cout<<"ConcreteAggregate()"<<endl;
        _pData = new Data[_size];
        for(int i=0;i<_size;++i)
                _pData[i] = i+1;
}
ConcreteAggregate::~ConcreteAggregate()
{
        cout<<"~ConcreteAggregate()"<<endl;
        delete _pData;
}
Iterator* ConcreteAggregate::createIterator()
{
        return new ConcreteIterator(this,0);  // 生成组合类对象
}
int ConcreteAggregate::size()
{
        return _size;
}
Data& ConcreteAggregate::getItem(int idx)
{
        return _pData[idx];
}
Iterator* ConcreteAggregate::begin()
{
        return new ConcreteIterator(this,0);  // 生成组合类对象
}
Iterator* ConcreteAggregate::end()
{
        return new ConcreteIterator(this,_size);  // 返回一个指向_pData末尾的Iterator对象
}
/*  *************************************  */
Iterator::~Iterator()
{
        cout<<"~Iterator()"<<endl;
}
ConcreteIterator::ConcreteIterator(Aggregate* pa,int idx):_pAggregate(pa),_idx(idx)
{
        cout<<"ConcreteIterator(Aggregate*,int)"<<endl;
}
ConcreteIterator::~ConcreteIterator()
{
        cout<<"~ConcreteIterator()"<<endl;
}
void ConcreteIterator::first()
{
        _idx = 0;  // 取Iterator类造出的对象的第一个元素
}
void ConcreteIterator::next()
{
        ++_idx;
}
bool ConcreteIterator::isDone()
{
        return _idx == _pAggregate->size();
}
Data& ConcreteIterator::currentItem()
{
        return _pAggregate->getItem(_idx);
}
int ConcreteIterator::index()
{
        return _idx;  // 获取Iterator类对象的大小
}
bool ConcreteIterator::operator!=(Iterator& rhs)
{
        return _idx != rhs.index();
}
Data& ConcreteIterator::operator*()
{
        return currentItem();
}
void ConcreteIterator::operator++()
{
        ++_idx;
}
// 提供一种方法顺序访问一个聚合对象中各个元素,,而又不需暴露该对象的内部表示. 
#include<iostream>
#include"iterator.h"
using namespace std;
int main()
{
        Aggregate* pAggregate = new ConcreteAggregate(5);
        Iterator* pIterator = pAggregate->createIterator();
        for(;false==pIterator->isDone();pIterator->next())
        {
                cout<<pIterator->currentItem()<<"  ";
        }
        cout<<endl<<endl;

        Iterator* it1 = pAggregate->begin();  // 建一个产品类指针,指向工厂类造的一个对象
        // 内部实现就是it1指向上面创建的数组的开头ConcreteIterator(this,0);
        Iterator* it2 = pAggregate->end();
        for(;(*it1)!=(*it2);++(*it1);)
        {
                cout<<*(*it1)<<endl;
        }
        delete pAggregate;
        delete pIterator;
        return 0;
}






posted on 2018-07-25 21:00  正在加载……  阅读(223)  评论(0编辑  收藏  举报