国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

這篇具有很好參考價(jià)值的文章主要介紹了【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

?文章來源地址http://www.zghlxwxcb.cn/news/detail-407231.html

?

文章目錄

  • 前言
  • 一、list的反向迭代器
  • ? ? ? ? vector的反向迭代器
  • 總結(jié)

?


前言

反向迭代器的適配只用于雙向迭代器,對(duì)于單鏈表實(shí)現(xiàn)的單向迭代器是不能通過適配構(gòu)造一個(gè)反向迭代器的,為什么要說反向迭代器適配器呢?因?yàn)槲覀冎恍枰獙?shí)現(xiàn)一個(gè)反向迭代器模板就可以用所有的雙向迭代器的正向?qū)崿F(xiàn)其反向迭代器。


提示:以下是本篇文章正文內(nèi)容,下面案例可供參考

一、list的反向迭代器

對(duì)于list而言,我們想要倒著遍歷該如何實(shí)現(xiàn)呢?其實(shí)實(shí)現(xiàn)過正向迭代器的朋友們都知道,list的迭代器的++是指向鏈表的下一個(gè)節(jié)點(diǎn),也就是node = node->next,那么要實(shí)現(xiàn)反向我們只需要將++實(shí)現(xiàn)為將node = node->prev即可,如下圖所示:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?

    //反向迭代器
	template<class T, class Ref, class Ptr>
	struct list_reverse_iterator
	{
		typedef list_node<T> node;
		typedef list_reverse_iterator<T, Ref, Ptr> self;
		node* _node;
		list_reverse_iterator(node* n)
			:_node(n)
		{

		}
		Ref operator*()
		{
			return _node->_data;
		}
		self& operator++()
		{
			_node = _node->_prev;
			return *this;
		}
		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}
		self& operator--()
		{
			_node = _node->_next;
			return *this;
		}
		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}
		Ptr operator->()
		{
			return &_node->_data;
		}
		bool operator!=(const self& it)
		{
			return _node != it._node;
		}
		bool operator==(const self& it)
		{
			return _node == it._node;
		}
	};

?可以看到我們上述代碼對(duì)于反向迭代器確實(shí)只是將++變成了原先的--,--變成了原先的++。現(xiàn)在我們?cè)賹懸幌聄begin(),rbegin().

class list
	{
	public:
		typedef list_node<T> node;
		typedef list_iterator<T, T&, T*> iterator;
		typedef list_iterator<T, const T&, const T*> const_iterator;
		typedef list_reverse_iterator<T, T&, T*> reverse_iterator;
		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);
		}
		reverse_iterator rbegin() 
		{
			return reverse_iterator(_head->_prev);
		}
		reverse_iterator rend() 
		{
			return reverse_iterator(_head);
		}

?我們先將反向迭代器重命名為reverse_list,然后讓rbegin()變成鏈表的尾節(jié)點(diǎn),rend()還是鏈表的哨兵位頭結(jié)點(diǎn)不變,下面我們來驗(yàn)證一下看是否正確:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?通過驗(yàn)證我們發(fā)現(xiàn)確實(shí)可以實(shí)現(xiàn)反向迭代,那么現(xiàn)在問題來了,我們剛開始說了反向迭代器是一個(gè)適配器,如果我們用這個(gè)鏈表的反向迭代器去實(shí)現(xiàn)vector的反向迭代器可以實(shí)現(xiàn)嗎?答案肯定是不行,因?yàn)関ector又不是節(jié)點(diǎn)怎么返回節(jié)點(diǎn)的前一個(gè)后一個(gè)呢?所以我們實(shí)現(xiàn)的這個(gè)迭代器只能list使用,下面我們看看大佬是如何實(shí)現(xiàn)反向迭代器的:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

我們?nèi)Τ鰜淼腸urrent是什么呢?current是一個(gè)正向迭代器

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想?那么為什么operator*變成了--迭代器然后解引用呢?再往下看:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?反向迭代器的++是正向迭代器的--,反向迭代器的--是正向迭代器的++。

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

我們發(fā)現(xiàn)rbegin()是迭代器的end(),rend()是迭代器的begin(),下面我們畫個(gè)圖來驗(yàn)證一下:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?這個(gè)時(shí)候我們終于理解了為什么operator*是--iterator的解引用,因?yàn)閞begin()是指向哨兵位的頭結(jié)點(diǎn)的,這個(gè)時(shí)候是不能對(duì)頭結(jié)點(diǎn)解引用的,所以我們應(yīng)該對(duì)頭結(jié)點(diǎn)的prev也就是最后一個(gè)節(jié)點(diǎn)解引用,這樣一來就能依次從后往前訪問到鏈表的每個(gè)元素,當(dāng)rbegin()==rend()的時(shí)候?qū)⑺性乇闅v完成。

下面我們就來實(shí)現(xiàn)一下:

namespace sxy
{
	template<class iterator,class Ref,class Ptr>
	struct ReverseIterator
	{
		typedef ReverseIterator<iterator, Ref, Ptr> self;
		iterator _cur;
		ReverseIterator(iterator it)
			:_cur(it)
		{

		}
	};
}

?首先我們創(chuàng)建一個(gè)iterator.h文件,然后寫一個(gè)模板這個(gè)模板第一個(gè)參數(shù)是任意類型的迭代器,第二個(gè)參數(shù)是迭代器中解引用的返回值Ref,第三個(gè)參數(shù)是在重載->符號(hào)的返回值Ptr。然后我們用正向迭代器創(chuàng)建一個(gè)變量_cur,構(gòu)造函數(shù)初始化的時(shí)候直接用正向迭代器初始化_cur.

然后我們先實(shí)現(xiàn)++,--:

        self& operator++()
		{
			--_cur;
			return *this;
		}
		self operator++(int)
		{
			iterator tmp = _cur;
			--_cur;
			return tmp;
		}

?對(duì)于前置++和后置++的區(qū)別在于后置++要返回--前的那個(gè)值,所以我們直接用拷貝構(gòu)造一個(gè)tmp,這里我們是沒有實(shí)現(xiàn)迭代器的拷貝構(gòu)造的,那么使用默認(rèn)的拷貝構(gòu)造可以嗎?答案是可以,因?yàn)槲覀円木褪菧\拷貝,我們就是要tmp指向cur位置,如下圖:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?我們?cè)倏匆幌律羁截愖兂闪耸裁矗?/p>

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

通過上圖我們應(yīng)該理解了為什么我們直接使用默認(rèn)的構(gòu)造函數(shù)就能解決問題。

        self& operator--()
		{
			++_cur;
			return *this;
		}
		self operator--(int)
		{
			iterator tmp = _cur;
			++_cur;
			return tmp;
		}

?對(duì)于--的實(shí)現(xiàn)是和++一樣的,只不過--變成了正向迭代器的++。

下面我們?cè)賹?shí)現(xiàn)一下迭代器要使用的==和!=符號(hào):

        bool operator!=(const self& s)
		{
			return _cur != s._cur;
		}
		bool operator==(const self& s)
		{
			return _cur == s._cur;
		}

?對(duì)于反向迭代器的判斷我們只需要判斷兩個(gè)反向迭代器的節(jié)點(diǎn)是否相等即可。

下面我們實(shí)現(xiàn)反向迭代器的解引用:

        Ref operator*()
		{
			iterator tmp = _cur;
			--tmp;
			return *tmp;
		}

?對(duì)于反向迭代器的解引用我們說過,由于rbegin()是在end()的位置所以我們是不能直接解引用的,正確的操作是解引用此位置的前一個(gè)節(jié)點(diǎn)(為什么是前一個(gè)呢?因?yàn)槭欠聪虻鳎。?。所以我們用_cur拷貝構(gòu)造一個(gè)tmp,然后--tmp就是前一個(gè)節(jié)點(diǎn),然后再返回解引用的值即可。返回值的實(shí)現(xiàn)與正向迭代器一樣具體可以去看我的list模擬實(shí)現(xiàn)那篇文章看看為什么要多一個(gè)模板參數(shù)Ref做返回值。

下面我們?cè)趌ist中定義一下反向迭代器:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?首先包含一下頭文件,然后typedef一下反向迭代器和反向迭代器的const版本:

typedef ReverseIterator<iterator,T&,T*> reverse_iterator;
typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;

        reverse_iterator rbegin() 
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend() 
		{
			return reverse_iterator(begin());
		}
		const_reverse_iterator rbegin() const
		{
			return const_reverse_iterator(end());
		}
		const_reverse_iterator rend() const
		{
			return const_reverse_iterator(begin());
		}

?接下來我們看看是否能成功反向輸出呢?

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

看來我們是成功了,那么回到我們一開始的問題,可以用這個(gè)迭代器去適配vector的反向迭代器嗎?我們畫個(gè)圖看看:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想?當(dāng)反向迭代器++的時(shí)候是正向迭代器的--,然后從vector的尾部開始向頭部移動(dòng)。同時(shí)我們發(fā)現(xiàn),operator*的實(shí)現(xiàn)也是滿足的,因?yàn)閞begin()的位置是vector存放最后一個(gè)有效數(shù)據(jù)的位置的下一個(gè),這個(gè)位置是沒有數(shù)據(jù)的,只有讓迭代器--一下在解引用才是正確的值,由于是每次位置的前一個(gè)所以當(dāng)rbegin()==rend()的時(shí)候?qū)⒎聪虮闅v完所有數(shù)據(jù),下面我們就演示一下vector的反向迭代器:

vector的反向迭代器

首先在vector.h的頭文件中包含iterator.h的頭文件:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

然后在vector中typedef一下反向迭代器:

typedef ReverseIterator<iterator, T&, T*> reverse_iterator;
typedef ReverseIterator<iterator, const T&, const T*> const_reverse_iterator;
        reverse_iterator rbegin()
		{
			return reverse_iterator(end());
		}
		reverse_iterator rend()
		{
			return reverse_iterator(begin());
		}
		const_reverse_iterator rbegin() const
		{
			return const_reverse_iterator(end());
		}
		const_reverse_iterator rend() const
		{
			return const_reverse_iterator(begin());
		}

?然后我們運(yùn)行一下程序看是否能成功:

【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想

?答案我們也看到了確實(shí)可以,這也就證明了我們一開始所說的大佬思想。當(dāng)我們想實(shí)現(xiàn)list的反向迭代器的時(shí)候只實(shí)現(xiàn)出針對(duì)list的反向迭代器,而大佬卻用一個(gè)反向迭代器適配其他的反向迭代器。

?


總結(jié)

對(duì)于迭代器的適配器最重要的是實(shí)現(xiàn)的思想,比如我們?nèi)绾慰刂茖?duì)迭代器進(jìn)行解引用,++--等等,想要有如同大佬一般的思想我們必須多看優(yōu)秀的代碼,只有去看別人寫的優(yōu)秀的代碼我們才能進(jìn)步。

?

?

到了這里,關(guān)于【c++】:反向迭代器適配器:每天學(xué)一點(diǎn)點(diǎn)優(yōu)秀的思想的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 深入篇【C++】手搓模擬實(shí)現(xiàn)list類(詳細(xì)剖析底層實(shí)現(xiàn)原理)&&模擬實(shí)現(xiàn)正反向迭代器【容器適配器模式】

    深入篇【C++】手搓模擬實(shí)現(xiàn)list類(詳細(xì)剖析底層實(shí)現(xiàn)原理)&&模擬實(shí)現(xiàn)正反向迭代器【容器適配器模式】

    1.一個(gè)模板參數(shù) 在模擬實(shí)現(xiàn)list之前,我們要理解list中的迭代器是如何實(shí)現(xiàn)的。 在vector中迭代器可以看成一個(gè)指針,指向vector中的數(shù)據(jù)。它的解引用會(huì)訪問到具體的數(shù)據(jù)本身,++會(huì)移動(dòng)到下一個(gè)數(shù)據(jù)位置上去,這些都是因?yàn)関ector具有天生的優(yōu)勢(shì):空間上是連續(xù)的數(shù)組,這樣指

    2024年02月15日
    瀏覽(34)
  • 面試之快速學(xué)習(xí)STL-迭代適配器

    面試之快速學(xué)習(xí)STL-迭代適配器

    參考:http://c.biancheng.net/view/7255.html 例子: 想使用反向迭代器實(shí)現(xiàn)逆序遍歷容器,則該容器的迭代器類型必須是雙向迭代器或者隨機(jī)訪問迭代器。 常見操作 注意這里不能用std::list,因?yàn)樗请p向迭代器, +3的操作需要隨機(jī)訪問迭代器 。故聯(lián)想到std::list排序只能使用list提供的

    2024年02月11日
    瀏覽(24)
  • C語言編程實(shí)現(xiàn),計(jì)算每天進(jìn)步一點(diǎn)點(diǎn)一年后的效果

    C語言編程實(shí)現(xiàn),計(jì)算每天進(jìn)步一點(diǎn)點(diǎn)一年后的效果

    本來的基數(shù)為1,如果好好學(xué)習(xí)時(shí)能力值相比前一天提高1%,當(dāng)放任時(shí)相比前一天下降1%。1年(365天)后的效果相差多少呢? 原基數(shù)為1,努力一天進(jìn)步1%,效果1*(1+0.01),努力兩天是在前一天的基礎(chǔ)上進(jìn)步1%,結(jié)果是1*(1+0.01)*(1+0.01),一年后天天向上的力量是(1+0.01)的365次方。

    2024年02月11日
    瀏覽(25)
  • 適配器模式(C++)

    適配器模式(C++)

    將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。 在軟件系統(tǒng)中,由于應(yīng)用環(huán)境的變化,常常需要將“一些現(xiàn)存的對(duì)象 ”放在新的環(huán)境中應(yīng)用,但是新環(huán)境要求的接口是這些現(xiàn)存對(duì)象所不滿足的。 如何

    2024年02月14日
    瀏覽(19)
  • C++適配器模式

    1 簡介: 適配器模式是一種結(jié)構(gòu)型設(shè)計(jì)模式,用于將一個(gè)類的接口轉(zhuǎn)換為客戶端所期望的另一個(gè)接口。適配器模式允許不兼容的類能夠協(xié)同工作,通過適配器類來實(shí)現(xiàn)接口的轉(zhuǎn)換和適配。 2 實(shí)現(xiàn)步驟: 以下是使用C++實(shí)現(xiàn)適配器模式的步驟: a. 定義目標(biāo)接口:首先,確定客戶

    2024年02月12日
    瀏覽(15)
  • C++附加篇: 空間適配器

    C++附加篇: 空間適配器

    ?\\\"我有時(shí)難過,卻還有些撫慰和感動(dòng)。\\\" ????????STL的六大組件,容器、算法、迭代器、適配器、仿函數(shù),最后一個(gè)也就是\\\"空間適配器\\\"。 ? ? ? ? 所謂\\\"空間適配器\\\",顧名思義,就是對(duì)STL中各個(gè)容器的內(nèi)存進(jìn)行高效的管理。也許你會(huì)說,誒,我寫了這么多的C++代碼,為什

    2023年04月19日
    瀏覽(21)
  • 【C++】手撕 棧 & 隊(duì)列(適配器)

    【C++】手撕 棧 & 隊(duì)列(適配器)

    目錄 一,stack 1,stack的介紹 2,stack 框架 3,push(const T x) 4,pop() 5,top() 6,size() 7,empty() 8,stack 測(cè)試 9,源代碼 二,queue 1,queue的介紹 2,queue 框架 3,push(const T x) 4,pop() 5,front() 6,back() 7,size() 8,empty() 9,queue 測(cè)試 10,源代碼 三,總結(jié) 1,stack 是一種容器適配器,專門用

    2024年04月15日
    瀏覽(20)
  • C++ [STL容器適配器]

    C++ [STL容器適配器]

    本文已收錄至《C++語言》專欄! 作者:ARMCSKGT 前面我們介紹了適配器模式中的反向迭代器,反向迭代器通過容器所支持的正向迭代器適配為具有反向迭代功能的迭代器,本節(jié)我們介紹STL中另一種適配器: 容器適配器 ! 前面我們提到過STL適配器模式,關(guān)于適配器的解釋: S

    2024年02月11日
    瀏覽(25)
  • C++之裝飾器&適配器模式

    C++之裝飾器&適配器模式

    目錄 一、裝飾器模式 模式思想 模式簡介 模式優(yōu)點(diǎn) 模式缺點(diǎn) 代碼實(shí)現(xiàn) 情景模擬 代碼實(shí)現(xiàn) 運(yùn)行結(jié)果 二、適配器模式 模式簡介 介紹 優(yōu)點(diǎn) 缺點(diǎn) 代碼實(shí)現(xiàn) 情景模擬 模式簡介 裝飾器模式( Decorator Pattern )允許向一個(gè)現(xiàn)有的對(duì)象 添加新的功能 ,同時(shí)又不改變其結(jié)構(gòu)。 這種類型

    2024年02月13日
    瀏覽(27)
  • 【C++】STL 算法 ⑩ ( 函數(shù)適配器 | 函數(shù)適配器概念 | 函數(shù)適配器分類 | 函數(shù)適配器輔助函數(shù) | std::bind2nd 函數(shù)原型及示例 | std::bind 函數(shù)原型及示例 )

    【C++】STL 算法 ⑩ ( 函數(shù)適配器 | 函數(shù)適配器概念 | 函數(shù)適配器分類 | 函數(shù)適配器輔助函數(shù) | std::bind2nd 函數(shù)原型及示例 | std::bind 函數(shù)原型及示例 )

    在 STL 中 預(yù)定義了很多 函數(shù)對(duì)象 , 如果要 對(duì) 函數(shù)對(duì)象 的 參數(shù) / 返回值 進(jìn)行 計(jì)算 或 設(shè)置 , 可以 使用 \\\" 函數(shù)適配器 \\\" 實(shí)現(xiàn)上述需求 ; \\\" 函數(shù)適配器 \\\" 可以 將 已存在的 函數(shù)對(duì)象 轉(zhuǎn)化為 另一種符合要求的 函數(shù)對(duì)象 ; \\\" 函數(shù)適配器 \\\" 定義在 functional 頭文件 中 ; \\\" 函數(shù)適配器

    2024年02月02日
    瀏覽(59)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包