Iteratorパターン

振る舞いに関するデザインパターン

「Iterate=反復する」にorをつけて「Iterator」。意味は反復子。

対象コンテナはなんであれ、アクセス方法を統一・独立させることにより、内部仕様に依存しない反復子を定義するためのパターン。

らしいです。



まぁとりあえずどんなものだか忘れないように書いてみるだ。


// イテレートするもの
template
class IteratedObject
{

public:

typedef Iterator iterator;
typedef IteratorReverse riterator;

public:
IteratedObject(int size);
virtual ~IteratedObject();
public:
Type* GetData(int index);
int GetSize();
private:
Type* m_pData;
int m_iSize;
};

template
IteratedObject::IteratedObject(int size):m_pData(NULL),m_iSize(size)
{
if (m_iSize != 0) {
m_pData = new Type[m_iSize];
}
}

template
IteratedObject::~IteratedObject()
{
if (m_pData) {
delete[] m_pData;
}
}

template
Type* IteratedObject::GetData(int index)
{
if (index >= m_iSize) {
return NULL;
}

return (m_pData + index);
}
template
int IteratedObject::GetSize()
{
return m_iSize;
}


//イテレーター基底
template
class IteratorBase
{
public:
IteratorBase(IteratedObject* p);
virtual ~IteratorBase();
public:
virtual Type* Current() = 0;
virtual void Next() = 0;
virtual Type* Begin() = 0;
virtual Type* End() = 0;
protected:
int m_iCount;
IteratedObject* m_pData;
};

template
IteratorBase::IteratorBase(IteratedObject* p):m_iCount(0),m_pData(p){}
template
IteratorBase::~IteratorBase(){
m_pData = NULL;
}

// イテレータ
template
class Iterator : public IteratorBase
{
public:
Iterator(IteratedObject* p);
~Iterator();
public:
Type* Current();
void Next();
Type* Begin();
Type* End();
};

template
Iterator::Iterator(IteratedObject* p)
:IteratorBase::IteratorBase(p){}

template
Iterator::~Iterator(){}

template
Type* Iterator::Current()
{
return m_pData->GetData(m_iCount);
}

template
void Iterator::Next()
{
if (m_iCount < m_pData->GetSize() - 1) {
++m_iCount;
}
}

template
Type* Iterator::Begin()
{
return m_pData->GetData(0);
}

template
Type* Iterator::End()
{
return m_pData->GetData(m_pData->GetSize() - 1);
}

// 逆進イテレータ
template
class IteratorReverse : public IteratorBase
{
public:
IteratorReverse(IteratedObject* p);
~IteratorReverse();
public:
Type* Current();
void Next();
Type* Begin();
Type* End();
};

template
IteratorReverse::IteratorReverse(IteratedObject* p)
:IteratorBase::IteratorBase(p)
{
m_iCount = p->GetSize() - 1;
}

template
IteratorReverse::~IteratorReverse(){}

template
Type* IteratorReverse::Current()
{
return m_pData->GetData(m_iCount);
}

template
void IteratorReverse::Next()
{
if (0 < m_iCount) {
--m_iCount;
}
}

template
Type* IteratorReverse::Begin()
{
int index = m_pData->GetSize() - 1;
return m_pData->GetData(index);
}

template
Type* IteratorReverse::End()
{
return m_pData->GetData(0);
}

// めいんー
int main()
{
IteratedObject Obj(100);

for (int i=0;i<100;i++) {
(*Obj.GetData(i)) = i;
}

IteratedObject::iterator ite(&Obj);
IteratedObject::riterator iter(&Obj);

while(iter.Current() != iter.End()) {

// 何かする!する!

iter.Next();
}


return 0;
}
(実行確認してないからエラーだらけかもw)

こんな感じ?

てか、ちゃんとした作り方わかんないです。

テンプレートも文法だけ覚えてて、使うのはほぼ初っていうね。

コレ見てる人で「使い方間違ってるぞ!」って方いたらコメントください。