簡單做網站百度外鏈查詢工具
意圖:提供一種方法順序訪問一個聚合對象中的各個元素,而又不需要暴露該對象的內部表示。
上下文:集合對象內部結構常常變化各異。對于這些集合對象,能否在不暴露其內部結構的同時,讓外部Client透明地訪問其中包含的元素,同時讓這種“透明遍歷”也為“同一種算法在多種集合對象上進行操作”提供可能?
UML
Iterator:定義訪問和遍歷元素的接口(.NET中定義了標準的IEnumrator接口)。ConcreteIterator:實現(xiàn)Iterator接口,同時在對Aggregate遍歷時跟蹤當前的位置。Aggregate:定義創(chuàng)建相應Iterator對象的接口(.NET中定義了標準的IEnumrable接口)。ConcreteAggregate:實現(xiàn)創(chuàng)建相應Iterator對象的接口,該操作返回一個適當?shù)腃oncreteIterator實例。
注意:.NET中的foreach關鍵字在編譯時會自動創(chuàng)建迭代器對象,并使用該對象對集合進行遍歷。.NET中的yield return關鍵字使得定義迭代器對象更加容易。
代碼
#include <iostream>
#include <list>
#include <array>
#include <vector>
using namespace std;//Iterator迭代器抽象類
class Iterator
{
public:virtual void* First() = 0;virtual void* Next() = 0;virtual bool IsDone() = 0;virtual void* CurrentItem() = 0;
};//Aggregate聚集抽象類
class Aggregate
{
public:virtual Iterator *CreateIterator() = 0;
};//ConcreteAggregate具體聚集類 繼承Aggregate
class ConcreteAggregate:public Aggregate
{
public:vector<void*> items;// Aggregate interface
public:Iterator *CreateIterator();int getCount() const;//既可以作為左值,也可以作為又值void** operator[](unsigned int index){if(items.size() <= index){items.resize(index+1);}return &items[index];}
};class ConcreteIterator:public Iterator
{
public:ConcreteAggregate *ca;int current;ConcreteIterator(ConcreteAggregate *c):ca(c){this->current = 0;}virtual void* First();virtual void* Next();virtual bool IsDone();virtual void* CurrentItem();
};Iterator *ConcreteAggregate::CreateIterator()
{return new ConcreteIterator(this);
}int ConcreteAggregate::getCount() const
{return items.size();
}void *ConcreteIterator::First()
{return *(*ca)[0];
}void *ConcreteIterator::Next()
{if(current < ca->getCount()){current++;}if(current < ca->getCount()){return *(*ca)[current];}return nullptr;
}bool ConcreteIterator::IsDone()
{return current >= ca->getCount()?true:false;
}void *ConcreteIterator::CurrentItem()
{return *(*ca)[current];
}class ConcreteIteratorDesc:public Iterator
{
public:ConcreteAggregate *ca;int current;ConcreteIteratorDesc(ConcreteAggregate *c):ca(c){this->current = c->getCount() - 1;}virtual void* First();virtual void* Next();virtual bool IsDone();virtual void* CurrentItem();
};
void *ConcreteIteratorDesc::First()
{if(ca->getCount() == 0){return nullptr;}return *(*ca)[ca->getCount() - 1];
}void *ConcreteIteratorDesc::Next()
{if(current >= 0){current--;}if(current >= 0){return *(*ca)[current];}return nullptr;
}bool ConcreteIteratorDesc::IsDone()
{return current < 0?true:false;
}
void *ConcreteIteratorDesc::CurrentItem()
{return *(*ca)[current];
}
int main()
{ConcreteAggregate ca;*(ca[0]) = (void*)5;*ca[1] = (void*)10;*ca[2] = (void*)15;*ca[3] = (void*)20;
// cout << (int) *ca[0] << endl;
// cout << (int) *ca[1] << endl;
// cout << ca.getCount() << endl;Iterator *i = new ConcreteIterator(&ca);cout << "開始遍歷" << endl;while(!i->IsDone()){cout << (int)i->CurrentItem() << endl;i->Next();}Iterator *i_desc = new ConcreteIteratorDesc(&ca);cout << "開始反向遍歷" << endl;while(!i_desc->IsDone()){cout << (int)i_desc->CurrentItem() << endl;i_desc->Next();}cout << "--end--" << endl;return 0;
}
結果:
開始遍歷
5
10
15
20
開始反向遍歷
20
15
10
5
--end--