迭代器模式?感觉很奇怪的名字。
这个名字是有些奇怪,不过我们在使用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;
}