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反向迭代器內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!