设计模式之迭代器模式(C++)

设计模式之迭代器模式

迭代器模式,提供一种方法顺序访问一个聚合对象中各个元素,而不暴露该对象的内部表示。该模式很好理解,C++中的迭代器应该都用过,和那个差不多。其UML图如下:
迭代器模式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;
}

测试结果如下图:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值