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; }