设计模式之迭代器模式
迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而不暴露该对象的内部表示。该模式很好理解,C++中的迭代器应该都用过,和那个差不多。其UML图如下:
ConcreteIterator内部有一个聚合对象的引用(指针),而ConcreteAggregate依赖于ConcreteIterator。以前向链表为例,示例代码如下:
// IteratorModel.h文件
#pragma once
#include <iostream>
// 单向链表
template<typename T>
class node
{
public:
node() : next(nullptr) { }
T data;
node * next;
};
// 迭代器
template<typename T>
class IteratorBase
{
public:
virtual T first() = 0;
virtual T next() = 0;
virtual bool isDone() = 0;
virtual T currentItem() = 0;
};
template<typename T>
class Iterator;
// 单项链表
template<typename T>
class forwardlist
{
public:
forwardlist();
~forwardlist();
private:
unsigned int m_nLength;
node<T> * m_HeadNode;
public:
friend class Iterator<T>;
T getElement(unsigned int index);
T getFirst();
T getTail();
unsigned int insertElement(unsigned int index, T elem);
unsigned int appendElement(T elem);
unsigned int insertFirst(T elem);
unsigned int setValue(unsigned int index, T value);
T deleteElement(unsigned int index);
void deleteAll();
unsigned int getLength();
bool empty();
Iterator<T> createIterator();
private:
node<T> * getFirstNode();
node<T> * getNode(unsigned int index);
};
// 具体的迭代器
template<typename T>
class Iterator : public IteratorBase<T>
{
private:
forwardlist<T> * m_list;
node<T> * m_pCurrentNode;
unsigned int m_nCurrentIndex;
public:
Iterator(forwardlist<T> * p):m_pCurrentNode(nullptr), m_nCurrentIndex(0u)
{
m_list = p;
m_pCurrentNode = m_list->getFirstNode();
}
T first()
{
return m_list->getFirst();
}
T next()
{
if (isDone())
return 0;
if (nullptr == m_pCurrentNode)
m_pCurrentNode = m_list->getNode(m_nCurrentIndex);
node<T> * p = m_pCurrentNode->next;
m_pCurrentNode = p;
m_nCurrentIndex++;
return p->data;
}
T currentItem()
{
return m_pCurrentNode->data;
}
bool isDone()
{
if (m_nCurrentIndex< m_list->getLength())
return false;
return true;
}
T operator*()
{
return currentItem();
}
};
// forwardlist函数实现
// 创建迭代器函数
template<typename T>
Iterator<T> forwardlist<T>::createIterator()
{
return Iterator<T>(this);
}
template<typename T>
forwardlist<T>::forwardlist() : m_nLength(0u), m_HeadNode(nullptr)
{
m_HeadNode = new node<T>;
}
template<typename T>
forwardlist<T>::~forwardlist()
{
deleteAll();
delete m_HeadNode;
}
template<typename T>
node<T> * forwardlist<T>::getNode(unsigned int index)
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
unsigned int n = 0;
node<T> * pnode = m_HeadNode;
while (n++ <= index)
{
pnode = pnode->next;
}
return pnode;
}
template<typename T>
T forwardlist<T>::getElement(unsigned int index)
{
return getNode(index)->data;
}
template<typename T>
T forwardlist<T>::getFirst()
{
return getElement(0u);
}
template<typename T>
T forwardlist<T>::getTail()
{
if (m_nLength == 0u)
{
return T;
}
return getElement(m_nLength - 1);
}
template<typename T>
unsigned int forwardlist<T>::insertElement(unsigned int index, T elem)
{
if (index > m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
node<T> * pnode = m_HeadNode;
unsigned int n = 0u;
while (n++ < index)// 定位到index上一个节点
{
pnode = pnode->next;
}
// 插入节点
node<T> *pnodeElem = new node<T>;
pnodeElem->data = elem;
pnodeElem->next = pnode->next;
pnode->next = pnodeElem;
// 长度增加
m_nLength++;
return index;
}
template<typename T>
unsigned int forwardlist<T>::insertFirst(T elem)
{
return insertElement(0u, elem);
}
template<typename T>
unsigned int forwardlist<T>::appendElement(T elem)
{
return insertElement(m_nLength, elem);
}
template<typename T>
unsigned int setValue(unsigned int index, T value)
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
node<T> * pnode = m_HeadNode;
while (n++ <= index)// 定位到index
{
pnode = pnode->next;
}
pnode->data = value;
return index;
}
template<typename T>
T forwardlist<T>::deleteElement(unsigned int index)
{
if (index >= m_nLength)
{
std::cout << "out of ranges" << std::endl;
return 0;
}
unsigned int n = 0u;
node<T> * pnode = m_HeadNode;
while (n++ < index)// 定位到index上一个节点
{
pnode = pnode->next;
}
// 删除节点
node<T> * pnodeTemp = pnode->next;
pnode->next = pnodeTemp->next;
T tTemp = pnodeTemp->data;
delete pnodeTemp;
pnodeTemp = nullptr;
// 长度减一
m_nLength--;
return tTemp;
}
template<typename T>
void forwardlist<T>::deleteAll()
{
while (m_nLength > 0)
{
deleteElement(0);
}
m_HeadNode->next = nullptr;
}
template<typename T>
unsigned int forwardlist<T>::getLength()
{
return m_nLength;
}
template<typename T>
bool forwardlist<T>::empty()
{
return m_nLength > 0 ? false : true;
}
template<typename T>
node<T> * forwardlist<T>::getFirstNode()
{
return getNode(0u);
}
测试代码如下:
#include <iostream>
#include "IteratorModel.h"
int main()
{
using namespace std;
// 迭代器模式
forwardlist<char> list;
list.insertElement(0u, 'A');
list.insertElement(1u, 'B');
list.insertElement(2u, 'C');
Iterator<char> it = list.createIterator();
std::cout << *it << endl;
std::cout << it.next() << endl;
std::cout << it.next() << endl;
cout << it.first() << endl;
cout << *it << endl;
if (!it.isDone())
cout << "结束" << endl;
else
cout << "未结束" << endl;
getchar();
return 0;
}
测试结果如下图: