设计模式C++版:第六式迭代器模式

迭代器模式?感觉很奇怪的名字。

这个名字是有些奇怪,不过我们在使用STL的时候,都用过迭代器。这时可能又有人问了这么平常的一种东西也是一种模式?

答案是肯定的。

世界上很多看起来习以为常的东西其实一点也不平常,甚至很难深入的理解。我们经常使用迭代器,可是如果你问一下迭代器到底是什么,肯定有很多人不能说的很清楚。在开始代码之前,我们先给出一个迭代器模式的定义好了:提供一种方法顺序访问一个聚合对象的各个元素,又不暴露该对象的内部表示。再简单一点,迭代器是一种访问聚合对象的一种表示。下面我们通过写一个list模板,来体会一下什么是迭代器模式:

Iterator.h


/*
**@the dark fairy tale**
**@16/7/28**
*/

//Node
template<class T>
struct CListNode
{
public:
	T data;
	CListNode<T>* next = nullptr;
	CListNode<T>* prev = nullptr;
};


//CList
template <class T>
class CList
{
public:
	class Iterator
	{
	public:
		Iterator() :m_node(nullptr){ }
		T & operator*();
		Iterator operator++(int);
		Iterator operator--(int);
		bool operator!=(const Iterator & lhs);
		bool operator==(const Iterator & lhs);

	protected:
		CListNode<T>* m_node;
		friend  CList<T>;
		Iterator(CListNode<T> *node) :m_node(node){	} //带参构造被调用
	};

public:
	CList();
	~CList();
	void push_back(const T node);	//尾部添加
	void pop_back();	//尾部删除
	Iterator& end();	//指向最后一个元素的下一个
	Iterator& begin();	//指向第一个元素
	Iterator insert(Iterator it, const T node);	//指定位置插入特定元素
	Iterator erase(Iterator it);		//删除特定元素
	unsigned int size();
	bool empty();
	void clear();		//清空
private:
	CListNode<T> * m_head;
	CListNode<T> * m_tail;
	unsigned int m_size;
};

//--------Iterator--------//

template<class T>
T & CList<T>::Iterator::operator*()
{
	return (*m_node).data;
}

template<class T>
typename CList<T>::Iterator CList<T>::Iterator::operator++(int)
{
	m_node = m_node->next;
	return *this;
}


template <class T>
typename CList<T>::Iterator CList<T>::Iterator::operator--(int)
{
	m_node = m_node->prev;
	return *this;
}



template <class T>
bool CList<T>::Iterator::operator!=(const Iterator & lhs)
{
	return !(*this == lhs);
}

template <class T>
bool CList<T>::Iterator::operator==(const Iterator & lhs)
{
	return this->m_node == lhs.m_node;
}

//----CList----//
template <class T>
typename CList<T>::Iterator CList<T>::erase(Iterator it)
{
	CListNode<T>*node = it.m_node;
	Iterator iter(node->next);
	node->next->prev = node->prev;
	node->prev->next = node->next;
	m_head->prev = m_tail;
	m_size--;
	delete node;

	return iter;
}

template <class T>
typename CList<T>::Iterator  CList<T>::insert(Iterator it, const T nodedata)
{
	CListNode<T>*node = it.m_node;
	CListNode<T>*newnode = new CListNode<T>;

	newnode->prev = node->next->prev;       //交换前指
	node->next->prev = newnode;

	newnode->next = node->next;
	node->next = newnode;
	m_head->prev = m_tail;

	newnode->data = nodedata;

	++m_size;
	return Iterator(newnode);
}

template <class T>
typename CList<T>::Iterator&  CList<T>::begin()
{
	return Iterator(m_head->next);
}

template <class T>
typename CList<T>::Iterator&  CList<T>::end()
{
	return Iterator(m_tail->next);
}

template <class T>
CList<T>::~CList()
{
	this->clear();
	delete m_head;
}

template <class T>
CList<T>::CList() :m_size(0)
{
	m_head = new CListNode<T>;
	m_tail = m_head;
	m_head->next = m_tail;
	m_head->prev = m_tail;
}

template <class T>
void CList<T>::pop_back()
{
	m_tail = m_tail->prev;   //前移
	delete m_tail->next;
	m_tail->next = m_head;
	m_head->prev = m_tail;

	--m_size;
}

template <class T>
void CList<T>::push_back(const T node)
{
	CListNode<T>*temp = m_tail;
	m_tail->next = new CListNode<T>;	//添加元素
	m_tail = m_tail->next;				//移动尾部
	m_tail->next = m_head;				//指向头部
	m_tail->prev = temp;				//前指
	m_tail->data = node;
	m_head->prev = m_tail;
	m_size++;
}

template<class T>
void CList<T>::clear()
{
	while (!empty())
		pop_back();
}

template <class T>
unsigned int CList<T>::size()
{
	return m_size;
}

template <class T>
bool CList<T>::empty()
{
	return m_size == 0;
}
/************************使用测试*******************************************/
#include "Iterator.h"
#include <stdio.h>
int main()
{
	CList<int>list;
	printf("after push_back-----------\n");
	for (int i = 0; i < 10; i++)
	{
		list.push_back(i);
	}

	CList<int>::Iterator iter = list.begin();
	CList<int>::Iterator iterend = list.end();
	for (; iter != iterend; iter++)
	{
		/*printf("%x,%x\n",iter,list.end());*/
		printf("%d\n", *iter);
	}

	printf("after pop_back-----------\n");
	list.pop_back();
	iter = list.begin();
	iterend = list.end();

	for (; iter != iterend; iter++)
	{
		printf("%d\n", *iter);
	}

	printf("after erase-----------\n");
	iter = list.begin();
	iter++;
	list.erase(iter);
	iter = list.begin();
	iterend = list.end();
	for (; iter != iterend; iter++)
	{
		printf("%d\n", *iter);
	}
	int a = 22;
	printf("after insert-----------\n");
	iter = list.end();
	for (int i = 0; i < 2; i++)
	{
		iter--;
	}

	list.insert(iter, a);
	iter = list.begin();
	iterend = list.end();
	for (; iter != iterend; iter++)
	{
		printf("%d\n", *iter);
	}

	printf("lsit size =%d\n", list.size());

	printf("after clear-----------\n");
	list.clear();
	iter = list.begin();
	iterend = list.end();
	for (; iter != iterend; iter++)
	{
		printf("%d\n", *iter);
	}

	printf(" is empty %d -----------\n", list.empty());

	return 0;
}



 
 
对于这个双向循环list的模板的实现,想必已经让你感觉到,“常用的东西原来竟然是这样的”! 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值