淺談C++反向迭代器的設計
前言
STL中不少的容器需要有迭代器這樣的設計,特別是正向迭代器,幾乎每個容器都有自己的特定實現(xiàn)方式,有了正向迭代器之后,我們還要提供反向迭代器以供一些特殊的需求,但是許多容器的正向迭代器實現(xiàn)的方式不一樣,如果我們要實現(xiàn)其反向迭代器,每個容器的反向迭代器的實現(xiàn)方式也不一樣,有沒有一種方法能夠統(tǒng)一反向迭代器的實現(xiàn)方式呢?
有的,那就是拿已有的正向迭代器進行封裝,這樣只要我們實現(xiàn)了正向迭代器,反向迭代器自然而然就形成了,本篇文章我們就來一起探究這種設計方式。
一、反向迭代器的結構
我們設計的反向迭代器是用正向迭代器實現(xiàn)的,這樣反向迭代器的實現(xiàn)方式就統(tǒng)一了,那么我們反向迭代器的成員變量就是一個正向迭代器,關于成員函數(shù),我們反向迭代器提供的接口與正向迭代器提供的接口一樣。
//第一個模板參數(shù)傳遞 正向迭代器,第二個傳遞 迭代器的引用 第三個傳遞 迭代器的地址 ?template<class Iterator, class Ref, class Ptr> ?//用struct定義類,因為我們想要公開我們的接口 ?struct _reverse_iterator ?{ ??? ?//對自己進行typedef方便使用 ??? ?typedef _reverse_iterator<Iterator, Ref, Ptr> self; ? ? //成員變量 是一個正向迭代器 ? ? Iterator _current; ? ? //構造函數(shù) ? 用一個正向迭代器進行初始化反向迭代器對象 ? ? _reverse_iterator(Iterator it) ? ? ? ? :_current(it) ? ? {} ? ? //*運算符重載 ? ? Ref operator*(); ? ? //前置++運算符重載 ? ? self& operator++(); ? ? //后置++運算符重載 ? ? self operator++(int) ? ? //前置--運算符重載 ? ? self& operator--() ? ? //后置--運算符 ? ? self operator--(int) ? ? //->操作符 ? ? Ptr operator->() ? ? //關系運算符 ? ? bool operator!=(const self& s); ? ? bool operator==(const self& s); ?}
容器類內的rbegin與rend 函數(shù)
//類內使用反向迭代器 class myclass { ? ? ?//此類內要配套有一個正向迭代器iterator,然后傳給外面的反向迭代器 ? ? ?//將反向迭代器進行typedef方便使用 ? ? ?typedef _reverse_iterator<iterator, T&, T*> reverse_iterator; ? ? ? //反向迭代器 ? ? ?typedef _reverse_iterator<iterator, const T&, const T*> const_reverse_iterator; ? ? ?//反向迭代器 ? ? ?reverse_iterator rbegin() ? ? ?{ ? ? ?? ?return reverse_iterator(end()); ? ? ?} ? ? ?reverse_iterator rend() ? ? ?{ ? ? ??? ?return reverse_iterator(begin()); ? ? ?} ? ? ?//const反向迭代器 ? ? ?const_reverse_iterator rbegin() const ? ? ?{ ? ? ??? ?return const_reverse_iterator(end()); ? ? ?} ? ? ?const_reverse_iterator rend() const ? ? ?{ ? ? ?? ?return const_reverse_iterator(begin()); ? ? ?} };
注意: 反向迭代器這里我們采用了對稱結構便于理解對比,但這也導致我們后面在進行*解引用操作符時要解引用前一個位置!
二、反向迭代器的接口實現(xiàn)
1、*運算符重載
我們可以創(chuàng)建一個局部對象,對局部對象進行--找到前一個位置,然后再進行解引用返回就行了。
//*運算符重載 Ref operator*() { //這里是不用寫拷貝構造的,默認的拷貝構造會對內置類型進行值拷貝,對自定義類型調用它的拷貝構造 Iterator tmp = _current; --tmp; return *tmp; }
2、算術運算符 ++ - -的重載
由于我們的反向迭代器是由正向迭代器實現(xiàn)的,反向迭代器++就相當于正向迭代器- - ,明白了這個就很好實現(xiàn)算術運算符重載了。
//前置++運算符重載 self& operator++() { --_current; return(*this); } //后置++運算符重載 self operator++(int) { //保存當前對象 self tmp(*this); --_current; //返回--之前的對象 return tmp; } //前置--運算符重載 self& operator--() { ++_current; return (*this); } //后置--運算符 self operator--(int) { self tmp(*this); ++_current; return tmp; }
3、->操作符重載
->運算符重載我們只需要返回容器中存儲的自定義類型的對象的地址就行了,我們可以先調用operator*()拿到容器中存儲的對象,然后再進行取地址&
Ptr operator->() { return &(operator*()); }
4、關系運算符
要判斷兩個反向迭代器相不相等,只需要判斷反向迭代器里面的成員變量相不相等就行了。
//關系運算符 bool operator!=(const self& s) { return _current != s._current; } bool operator==(const self& s) { return _current == s._current; }
到這里我們的反向迭代器就已經形成了。
三、關于反向迭代器的一些討論
由于我們的反向迭代器是用模板寫的,當我們將vector的迭代器類型傳遞過去時,我們的反向迭代器就變成了vector的反向迭代器,當我們將list的迭代器傳遞過去時,就形成了list的反向迭代器。
傳遞的迭代器必須的二元迭代器,可以++ ,- -。forward_list的迭代器就不行!
例如:實現(xiàn)vector的反向迭代器,我們只需要在類內部傳遞一下正向迭代器,然后typedef一下就行了。
template<class T> class vector { public: ?? ?//正向迭代器 ?? ?typedef ?T* iterator; ?? ?//反向迭代器 ? 將正向迭代器進行傳遞給反向迭代器 ?? ?typedef _reverse_iterator<iterator, T&, T*> reverse_iterator; ?? ?typedef _reverse_iterator<iterator, const T&, const T*> const_reverse_iterator; ?? ?//普通迭代器 ?------------------------------------------------ ?? ?iterator begin(); ?? ?iterator end(); ?? ?//const迭代器 ?? ?typedef const T* const_iterator; ?? ?const_iterator begin() const; ?? ?const_iterator end() const; ?? ?//反向迭代器 ?? ?reverse_iterator rbegin() ?? ?{ ?? ??? ?return reverse_iterator(end()); ?? ?} ?? ?reverse_iterator rend() ?? ?{ ?? ??? ?return reverse_iterator(begin()); ?? ?} ?? ?//const反向迭代器 ?? ?const_reverse_iterator rbegin() const ?? ?{ ?? ??? ?return const_reverse_iterator(end()); ?? ?} ?? ?const_reverse_iterator rend() const ?? ?{ ?? ??? ?return const_reverse_iterator(begin()); ?? ?} ?? ?......? ?? ?......? ?? ?......? };
到此這篇關于淺談C++反向迭代器的設計的文章就介紹到這了,更多相關C++反向迭代器內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
用C語言實現(xiàn)從文本文件中讀取數(shù)據后進行排序的功能
這是一個十分可靠的程序,這個程序的查錯能力非常強悍。程序包含了文件操作,歸并排序和字符串輸入等多種技術。對大家學習C語言很有幫助,有需要的一起來看看。2016-08-08C++實現(xiàn)LeetCode(309.買股票的最佳時間含冷凍期)
這篇文章主要介紹了C++實現(xiàn)LeetCode(309.買股票的最佳時間含冷凍期),本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下2021-08-08C++智能指針shared_ptr與weak_ptr的實現(xiàn)分析
shared_ptr是一個標準的共享所有權的智能指針,允許多個指針指向同一個對象,定義在 memory 文件中,命名空間為 std,這篇文章主要介紹了C++ 中 shared_ptr weak_ptr,需要的朋友可以參考下2022-09-09