C++ STL反向迭代器的实现
反向迭代器其实就行对正向迭代器进行封装,源生迭代器,为了实现运算符的结果不同,正向迭代器也对源生迭代器进行了封装。
反向迭代器的适配器,就是 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); }
到此这篇关于C++ STL反向迭代器的实现的文章就介绍到这了,更多相关C++ STL反向迭代器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特
这篇文章主要介绍了Qt GUI图形图像开发之QT表格控件QTableView,QTableWidget复杂表头(多行表头) 及冻结、固定特定的行的详细方法与实例,需要的朋友可以参考下2020-03-03
最新评论