C++ STL反向迭代器
酬 勤 人气:0反向迭代器其实就行对正向迭代器进行封装,源生迭代器,为了实现运算符的结果不同,正向迭代器也对源生迭代器进行了封装。
反向迭代器的适配器,就是 Iterator是哪个容器的迭代器,reverse_iterator < Iterator >就可以 适配出哪个容器的反向迭代器。复用的体现。
反向迭代器适配器结构:
template <class Iterator, class Ref, class Ptr> class reverse_iterator { typedef reverse_iterator<Iterator, Ref, Ptr> self; public: // 重载运算符函数 private: Iterator _it; };
源码容器获取迭代器时具体情况,如图:
我们以为的情况:
这是源码里的实现的大概情况,begin()与rend()对称,end()与rbegin()对称。这与我们想的不一样,所以反向迭代器适配器内部实现的也有所不一样。例如:
如果我们按照源码的思路写,反向迭代器里封装了一个正向迭代器_it,正常的++,–等操作只需要调用_it的–,++运算符重载函数即可。除了,operator*需要特写,如下代码:
Ref operator*() { //正常思路 //return *_it; // 源码思路 Iterator prev = _it; return *--prev; }
正常情况是解引用迭代器,但是源码的思路是往后一个位置的迭代器才是。这也是因为rbegin,和rend实现的原因导致的。
适配出来的反向迭代器其用法和正向迭代器一样;
反向迭代器根正向迭代器区别就是++、–的方向是相反的所以反向迭代器封装正向迭代器即可,重载控制++、–的方向。
源码的设计追求对称,我们设计可以不按源码走,在容器实现rbegin(),rend()时,要按照反向迭代器的设计风格去实现。
list完整样例:
1、反向迭代器适配器
// Iterator是哪个容器的迭代器,reverse_iterator<Iterator>就可以 // 适配出哪个容器的反向迭代器。复用的体现 template <class Iterator, class Ref, class Ptr> class reverse_iterator { typedef reverse_iterator<Iterator, Ref, Ptr> self; public: reverse_iterator(Iterator it) :_it(it) {} Ref operator*() { //正常思路 //return *_it; Iterator prev = _it; return *--prev; } Ptr operator->() { return &operator*(); } self& operator++() { --_it; return *this; } self& operator--() { ++_it; return *this; } bool operator!= (const self& rit) { return _it != rit._it; } private: Iterator _it;// 封装任何类型的正向迭代器 };
二、list 正向迭代器
// iterator -> 类去分装节点指针,重载*、++ 等运算符,让它们像指针一样使用 template<class T,class Ref,class Ptr> class _list_iterator { public: typedef _list_iterator < T, Ref,Ptr> self; typedef ListNode<T> Node; _list_iterator( Node* x) :_node(x) {} // ++it self& operator++() { _node = _node->_next; return *this; } // it++ self operator++(int) { self tmp(*this); _node = _node->_next; return tmp; } // --it self& operator--() { _node = _node->_pre; return *this; } // it-- self operator--(int) { self tmp(*this); _node = _node->_pre; return tmp; } //* Ref operator*() { return _node->_data; } //-> Ptr operator->() { return &(_node->_data); } //!= bool operator!=(const self& x) { return _node != x._node; } //== bool operator==(const self& x) { return _node == x._node; } Node* _node; };
三、 list容器
注意:这里只涉及反向迭代器的内容
template<class T> class list { public: typedef ListNode<T> Node; typedef _list_iterator<T, T&, T*> iterator; typedef _list_iterator<T, const T&, const T*> const_iterator; typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator; typedef reverse_iterator<iterator, T&, T*> reverse_iterator; reverse_iterator rbegin() { return reverse_iterator(end()); } const_reverse_iterator rbegin()const { return const_reverse_iterator(end()); } reverse_iterator rend() { return reverse_iterator(begin()); } const_reverse_iterator rend()const { return const_reverse_iterator(begin()); } iterator begin() { return iterator(_head->_next); } iterator end() { return iterator(_head); } const_iterator begin()const { return const_iterator(_head->_next); } const_iterator end()const { return const_iterator(_head); } list() { _head= new Node(); _head->_next = _head; _head->_pre = _head; } void push_back(const T&x) { Node* newnode = new Node(x); Node* tail = _head->_pre; newnode-> _pre = tail; tail->_next = newnode; newnode->_next = _head; _head->_pre = newnode; } private: Node* _head;// 头结点指针 };
测试代码:
void test11() { BBQ::list<int> L1; L1.push_back(1); L1.push_back(2); L1.push_back(3); reverse_print_list(L1); }
加载全部内容