您好,登錄后才能下訂單哦!
本篇內容介紹了“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反向迭代器如何實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。