C++ 迭代器模式实现

STL模板库中有大量迭代器实现,这些迭代器隔离了算法实现与访问接口,我们也可以编写属于自己的迭代器。STL中的迭代器均继承至一个通用迭代器接口:

template <class _Category, class _Tp, class _Distance = ptrdiff_t,
          class _Pointer = _Tp*, class _Reference = _Tp&>
struct iterator {
  typedef _Category  iterator_category; //迭代器类型
  typedef _Tp        value_type;
  typedef _Distance  difference_type;
  typedef _Pointer   pointer;
  typedef _Reference reference;
};

迭代器类型用于指明实例化迭代器的标签,如:输入迭代器(写)、输出迭代器(读)、随机访问迭代器等,算法可通过不同迭代器种类来实现各版本。

__distance算法就针对不同迭代器不同的实现:

template <class _InputIterator, class _Distance>
inline void __distance(_InputIterator __first, _InputIterator __last,
                       _Distance& __n, input_iterator_tag)
{
  while (__first != __last) { ++__first; ++__n; }
}

template <class _RandomAccessIterator, class _Distance>
inline void __distance(_RandomAccessIterator __first, 
                       _RandomAccessIterator __last, 
                       _Distance& __n, random_access_iterator_tag)
{
  __STL_REQUIRES(_RandomAccessIterator, _RandomAccessIterator);
  __n += __last - __first;
}

所有的迭代器种类声明如下:

struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};

 迭代器的重要方法如下:

T& operator*() const 
T* operator->() const 
bool operator==(const iterator & __x) const
bool operator!=(const iterator & __x) const 
iterator& operator++()
iterator operator++(int)

 这样就可以实现自己的迭代器了:

#include <iostream>
#include <iterator>

using namespace std;

template <typename T>
struct _A_node {
	_A_node *next;
	_A_node *prev;
	T data;
};

template <typename T>
class A_Iterator:public iterator<forward_iterator_tag,T>
{
private:
	typedef A_Iterator<T> self;

	_A_node<T> *_node;
	void incr()
	{
		_node = _node->next;
	}
	
	void decr()
	{
		_node = (_A_node<T>*)_node->prev;
	}
	
public:
	A_Iterator():_node(0) {}
	A_Iterator(_A_node<T> *x):_node(x) {}
	~A_Iterator() {}
	
	T& operator*() const { return _node->data;}
	T* operator->() const {return &(operator*());}
	
	bool operator==(const self& __x) const {
		return _node == __x._node;
	}

	bool operator!=(const self& __x) const {
		return _node != __x._node;
	}

	self& operator++() { incr(); return *this;}
	self operator++(int) { self __tmp = *this; incr(); return __tmp;}
	
	self& operator--() {decr();return *this;}
	self operator--(int) {self __tmp = *this; decr();return __tmp;}

};

template <typename T>
class A {
private:
	typedef T Node;
	_A_node<T> *pNode;
public:
	typedef A_Iterator<T> iterator;
	typedef _A_node<T> _Node;

	A() {
		pNode = new _A_node<T>;
		pNode->next = pNode;
		pNode->prev = pNode;
	}
	~A() {
		//add delete node function here
		delete pNode;
	}

	iterator begin() {return (_Node *)(pNode->next);}
	iterator end() {return pNode;}	

	///////////////// method /////////////////////
	void push(T value) 
	{
		_A_node<T> *v = new _A_node<T>;
		v->data = value;

		v->next = pNode->next;
		pNode->next->prev = v;

		pNode->next = v;
		v->prev = pNode;
		
	}

	T pop() 
	{
		T value;

		_Node *next = pNode->next;
		pNode->next = next->next;
		next->prev = pNode;

		next->prev = next;
		next->next = next;
		
		value =  next->data;
		delete next;
		
		return value;
	}
};

int main(int argc, char *argv[])
{
	A<int> a;
	a.push(1);
	a.push(2);
	a.pop();
	for(A<int>::iterator iter = a.begin();iter != a.end();iter++) {
			*iter = 3;
			std::cout << "value:" << *iter << std::endl;
	}
	
	int b = a.pop();

	std::cout << (a.begin() == a.end()) << ",b:" << b << std::endl;
	return 0;
}

若需增加const_iterator则需要进行重写另一个iterator,也可以通过修改iterator模板声明格式进行修改,满足其iterator格式,最终版本如下:

#include <iostream>
#include <iterator>

using namespace std;

template <typename T>
struct _A_node {
	_A_node *next;
	_A_node *prev;
	T data;
};

template <class T,class Ref,class Ptr>
class A_Iterator:public iterator<forward_iterator_tag,T>
{
public:
	typedef A_Iterator<T,T&,T*> iterator;
	typedef A_Iterator<T,const T&,const T*> const_iterator;
private:
	typedef A_Iterator<T,Ref,Ptr> self;

	_A_node<T> *_node;
	void incr()
	{
		_node = _node->next;
	}
	
	void decr()
	{
		_node = (_A_node<T>*)_node->prev;
	}
	
public:
	A_Iterator():_node(0) {}
	A_Iterator(_A_node<T> *x):_node(x) {}
	~A_Iterator() {}
	
	Ref operator*() const { return _node->data;}
	Ptr operator->() const {return &(operator*());}
	
	bool operator==(const self& __x) const {
		return _node == __x._node;
	}

	bool operator!=(const self& __x) const {
		return _node != __x._node;
	}

	self& operator++() { incr(); return *this;}
	self operator++(int) { self __tmp = *this; incr(); return __tmp;}
};



template <typename T>
class A {
private:
	typedef T Node;
	_A_node<T> *pNode;
public:
	typedef typename A_Iterator<T,T&,T*>::iterator iterator;
	typedef typename A_Iterator<T,const T&,const T*>::const_iterator const_iterator;
	typedef _A_node<T> _Node;

	A() {
		pNode = new _A_node<T>;
		pNode->next = pNode;
		pNode->prev = pNode;
	}
	~A() {
		//add delete node function here
		delete pNode;
	}

	iterator begin() {return (_Node *)(pNode->next);}
	iterator end() {return pNode;}	
	
	const_iterator const_begin() const {return (_Node *)(pNode->next);}
	const_iterator const_end() const {return pNode;}
	
	///////////////// method /////////////////////
	void push(T value) 
	{
		_A_node<T> *v = new _A_node<T>;
		v->data = value;

		v->next = pNode->next;
		pNode->next->prev = v;

		pNode->next = v;
		v->prev = pNode;
		
	}

	T pop() 
	{
		T value;

		_Node *next = pNode->next;
		pNode->next = next->next;
		next->prev = pNode;

		next->prev = next;
		next->next = next;
		
		value =  next->data;
		delete next;
		
		return value;
	}
};

int main(int argc, char *argv[])
{
	A<int> a;
	a.push(1);
	a.push(2);
	//a.pop();
	/*
	for(A<int>::iterator iter = a.begin();iter != a.end();iter++) {
			*iter = 3;
			std::cout << "value:" << *iter << std::endl;
	}
	*/
	//A<int>::const_iterator iter = a.const_begin();
	
	for(A<int>::const_iterator iter = a.const_begin();iter != a.const_end();iter++) {
		//*iter = 3;
		std::cout << "value:" << *iter << std::endl;
	}
	
	int b = a.pop();

	std::cout << (a.begin() == a.end()) << ",b:" << b << std::endl;
	return 0;
}

posted on 2015-06-08 09:54  kkford  阅读(1363)  评论(0编辑  收藏  举报

导航