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

C++:模擬實(shí)現(xiàn)list及迭代器類模板優(yōu)化方法

這篇具有很好參考價(jià)值的文章主要介紹了C++:模擬實(shí)現(xiàn)list及迭代器類模板優(yōu)化方法。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

本篇模擬實(shí)現(xiàn)簡(jiǎn)單的list和一些其他注意的點(diǎn)

C++:模擬實(shí)現(xiàn)list及迭代器類模板優(yōu)化方法,C++,# 模擬實(shí)現(xiàn),知識(shí)總結(jié),c++

迭代器

如下所示是利用拷貝構(gòu)造將一個(gè)鏈表中的數(shù)據(jù)挪動(dòng)到另外一個(gè)鏈表中,構(gòu)造兩個(gè)相同的鏈表

list(const list<T>& lt)
{
	emptyinit();
	for (auto e : lt)
	{
		push_back(e);
	}
}

void test_list1()
{
	list<int> lt;
	lt.push_back(1);
	lt.push_back(2);
	lt.push_back(3);
	lt.push_back(4);
	lt.push_back(5);

	list<int> l2(lt);
}

lt作為形參,傳引用可以提高傳參的效率,同時(shí)應(yīng)該加上const修飾來保證不會(huì)因?yàn)椴恍⌒男薷牧诵螀?dǎo)致外部的實(shí)參也被修改,這樣的結(jié)果是不應(yīng)該的,因此就要加const把這個(gè)形參變成一個(gè)const對(duì)象

而問題又來了,const對(duì)象要使用的是const迭代器,而前面沒有寫const迭代器,因此這里就引入了const迭代器的實(shí)現(xiàn)

從vector的模擬實(shí)現(xiàn)中,看似似乎只需要在原來的迭代器的基礎(chǔ)上加上一個(gè)const即可,但事實(shí)上:

const迭代器和普通迭代器是兩種不同的迭代器,不能直接在普通的迭代器后面加const,原因?

要解決這個(gè)問題,先重新回顧一下vector中const迭代器的定義流程:

對(duì)比vector的迭代器,vector中的迭代器const版本和非const版本直接在非const版本后面加const使它變成const迭代器即可,這樣在調(diào)用的時(shí)候就可以直接進(jìn)行調(diào)用

C++:模擬實(shí)現(xiàn)list及迭代器類模板優(yōu)化方法,C++,# 模擬實(shí)現(xiàn),知識(shí)總結(jié),c++

對(duì)iterator的定義,const版本就是在指針前面加上const,這樣返回的就是const修飾的指針,因此就可以做到通過該迭代器只讀,不可修改的作用

C++:模擬實(shí)現(xiàn)list及迭代器類模板優(yōu)化方法,C++,# 模擬實(shí)現(xiàn),知識(shí)總結(jié),c++

這里的迭代器本質(zhì)上就是指針在底層進(jìn)行訪問,然后我們定義一個(gè)const指針,使得const指針就不能對(duì)指針指向的內(nèi)容進(jìn)行修改了

下面仿照vector修改的原理修改list

要修改的部分其實(shí)就是下面的代碼:

iterator begin()
{
	return iterator(_head->_next);
}

iterator end()
{
	return iterator(_head);
}

在函數(shù)后加const很簡(jiǎn)單,但是核心是要把返回值也定義為const指針版本,這個(gè)過程要如何實(shí)現(xiàn)?

由于這里是把iterator封裝成了一個(gè)類進(jìn)行的實(shí)現(xiàn),因此需要重新封裝一個(gè)類進(jìn)行實(shí)現(xiàn)

	template <class T>
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef  __list_iterator<T> self;
		// 成員
		Node* _node;

		__list_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

		T& operator*()
		{
			return _node->_data;
		}

		T* operator->()
		{
			return &_node->_data;
		}

		bool operator==(const self& pos)
		{
			return _node == pos._node;
		}

		bool operator!=(const self& pos)
		{
			return !(*this == pos);
		}
	};

	template <class T>
	struct __list_const_iterator
	{
		typedef list_node<T> Node;
		typedef  __list_const_iterator<T> self;
		// 成員
		Node* _node;

		__list_const_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

		const T& operator*()
		{
			return _node->_data;
		}

		const T* operator->()
		{
			return &_node->_data;
		}

		bool operator==(const self& pos)
		{
			return _node == pos._node;
		}

		bool operator!=(const self& pos)
		{
			return !(*this == pos);
		}
	};

但事實(shí)上,這兩份代碼只有很少的地方有區(qū)別,更多的內(nèi)容都是相同的,這樣是不滿足較好的代碼風(fēng)格,因此在stl源碼中,使用了模板對(duì)這兩個(gè)類進(jìn)行了封裝

改進(jìn)版本如下:

	template <class T, class Ref, class Ptr >
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef  __list_iterator<T, Ref, Ptr> self;
		// 成員
		Node* _node;

		__list_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}

		bool operator==(const self& pos)
		{
			return _node == pos._node;
		}

		bool operator!=(const self& pos)
		{
			return !(*this == pos);
		}
	};

	template <class T>
	class list
	{
		void emptyinit()
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
			_size = 0;
		}
	public:
		typedef list_node<T> Node;
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;

		// 構(gòu)造函數(shù) 
		list()
		{
			emptyinit();
		}
		// 拷貝構(gòu)造
		list(const list<T>& lt)
		{
			emptyinit();
			auto it = lt.begin();
			//*it = 30;
		}

		void push_back(const T& x)
		{
			insert(end(), x);
		}

		void push_front(const T& x)
		{
			insert(begin(), x);
		}

		// head     tail->prev  tail
		void pop_back()
		{
			erase(--end());
		}

		void pop_front()
		{
			erase(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);
		}

		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* newnode = new Node(x);

			//        newnode
			//   prev         cur
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;

			return iterator(newnode);
		}

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			// prev cur next
			prev->_next = cur->_next;
			next->_prev = cur->_prev;

			return iterator(next);
		}

	private:
		Node* _head;
		size_t _size;
	};

這里引入了類模板的概念,簡(jiǎn)單來說,當(dāng)需要調(diào)用const類型時(shí)就會(huì)模板實(shí)例化出一個(gè)const版本的迭代器,再進(jìn)行相關(guān)的操作,這樣的操作可以避免代碼冗余,也是模板的強(qiáng)大之處文章來源地址http://www.zghlxwxcb.cn/news/detail-649281.html

模擬實(shí)現(xiàn)

#pragma once

// 實(shí)現(xiàn)的是雙向循環(huán)鏈表,鏈表中應(yīng)該包含節(jié)點(diǎn)類和迭代器類,節(jié)點(diǎn)類用于從內(nèi)存中申請(qǐng)節(jié)點(diǎn),迭代器類用于獲取節(jié)點(diǎn)指針
namespace mylist
{
	// 把節(jié)點(diǎn)進(jìn)行封裝,可以動(dòng)態(tài)獲取一個(gè)節(jié)點(diǎn)
	template <class T>
	struct list_node
	{
		// 成員
		list_node<T>* _next;
		list_node<T>* _prev;
		T _data;

		// 成員函數(shù)
		list_node(const T& val = T())
			:_data(val)
			, _next(nullptr)
			, _prev(nullptr)
		{}
	};

	// 對(duì)迭代器進(jìn)行封裝,使得外界看到的是迭代器
	// 迭代器當(dāng)中存儲(chǔ)的是某個(gè)節(jié)點(diǎn)的指針
	// 可以對(duì)迭代器進(jìn)行各項(xiàng)操作
	template <class T, class Ref, class Ptr >
	struct __list_iterator
	{
		typedef list_node<T> Node;
		typedef  __list_iterator<T, Ref, Ptr> self;
		// 成員
		Node* _node;

		__list_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_next;
			return *this;
		}

		self& operator--()
		{
			_node = _node->_prev;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}

		bool operator==(const self& pos)
		{
			return _node == pos._node;
		}

		bool operator!=(const self& pos)
		{
			return !(*this == pos);
		}
	};

	// 適配器 -- 復(fù)用
	template <class T, class Ref, class Ptr >
	struct __reverse_iterator
	{
		typedef list_node<T> Node;
		typedef  __reverse_iterator<T, Ref, Ptr> self;
		// 成員
		Node* _node;

		__reverse_iterator(Node* node)
			:_node(node)
		{}

		self& operator++()
		{
			_node = _node->_prev;
			return *this;
		}

		self& operator--()
		{
			_node = _node->_next;
			return *this;
		}

		self operator++(int)
		{
			self tmp(*this);
			_node = _node->_prev;
			return tmp;
		}

		self operator--(int)
		{
			self tmp(*this);
			_node = _node->_next;
			return tmp;
		}

		Ref operator*()
		{
			return _node->_data;
		}

		Ptr operator->()
		{
			return &_node->_data;
		}

		bool operator==(const self& pos)
		{
			return _node == pos._node;
		}

		bool operator!=(const self& pos)
		{
			return !(*this == pos);
		}
	};


	template <class T>
	class list
	{
		void emptyinit()
		{
			_head = new Node();
			_head->_next = _head;
			_head->_prev = _head;
			_size = 0;
		}
	public:
		typedef list_node<T> Node;
		typedef __list_iterator<T, T&, T*> iterator;
		typedef __list_iterator<T, const T&, const T*> const_iterator;
		typedef __reverse_iterator<T, T&, T*> reverse_iterator;
		typedef __reverse_iterator<T, const T&, const T*> const_reverse_iterator;

		// 構(gòu)造函數(shù) 
		list()
		{
			emptyinit();
		}
		// 拷貝構(gòu)造
		list(const list<T>& lt)
		{
			emptyinit();
			auto it = lt.begin();
			//*it = 30;
		}

		void push_back(const T& x)
		{
			insert(end(), x);
		}

		void push_front(const T& x)
		{
			insert(begin(), x);
		}

		// head     tail->prev  tail
		void pop_back()
		{
			erase(--end());
		}

		void pop_front()
		{
			erase(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);
		}

		reverse_iterator rbegin()
		{
			return reverse_iterator(_head->_prev);
		}

		reverse_iterator rend()
		{
			return reverse_iterator(_head);
		}

		const_reverse_iterator rbegin() const
		{
			return const_reverse_iterator(_head->_prev);
		}

		const_reverse_iterator rend() const
		{
			return const_reverse_iterator(_head);
		}

		iterator insert(iterator pos, const T& x)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* newnode = new Node(x);

			//        newnode
			//   prev         cur
			prev->_next = newnode;
			newnode->_prev = prev;
			newnode->_next = cur;
			cur->_prev = newnode;

			return iterator(newnode);
		}

		iterator erase(iterator pos)
		{
			Node* cur = pos._node;
			Node* prev = cur->_prev;
			Node* next = cur->_next;

			// prev cur next
			prev->_next = cur->_next;
			next->_prev = cur->_prev;

			return iterator(next);
		}

	private:
		Node* _head;
		size_t _size;
	};


	void test_list1()
	{
		list<int> lt;
		lt.push_back(1);
		lt.push_back(2);
		lt.push_back(3);
		lt.push_back(4);
		lt.push_back(5);
		
		cout << "正序" << endl;
		for (auto e : lt)
		{
			cout << e << " ";
		}
		cout << endl;

		cout << "逆序" << endl;
		auto rit = lt.rbegin();
		while (rit != lt.rend())
		{
			cout << *rit << " ";
			rit++;
		}
		cout << endl;
	}
}

到了這里,關(guān)于C++:模擬實(shí)現(xiàn)list及迭代器類模板優(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)文章

  • STL之list模擬實(shí)現(xiàn)(反向迭代器講解以及迭代器失效)

    這次是關(guān)于list的模擬實(shí)現(xiàn)的代碼,先看看下面的代碼: 上面是list的代碼,其底層是一個(gè)帶頭雙向循環(huán)的鏈表,實(shí)現(xiàn)的方法就不說了,相信大家已經(jīng)都會(huì)了,然后自己實(shí)心的list我沒有寫析構(gòu)函數(shù)等,這個(gè)也很簡(jiǎn)單,循環(huán)利用成員函數(shù)中的刪除函數(shù)就可以。 先來說說個(gè)人認(rèn)為

    2024年02月11日
    瀏覽(19)
  • list【2】模擬實(shí)現(xiàn)(含迭代器實(shí)現(xiàn)超詳解哦)

    list【2】模擬實(shí)現(xiàn)(含迭代器實(shí)現(xiàn)超詳解哦)

    在前面,我們介紹了list的使用: 戳我看list的介紹與使用詳解哦 在本篇文章中將重點(diǎn)介紹list的接口實(shí)現(xiàn),通過模擬實(shí)現(xiàn)可以更深入的理解與使用list 我們模擬實(shí)現(xiàn)的 list 底層是一個(gè)帶頭雙向循環(huán)鏈表 在實(shí)現(xiàn)list時(shí),我們首先需要一個(gè) 結(jié)構(gòu)體以表示鏈表中結(jié)點(diǎn)的結(jié)構(gòu) list_node ,

    2024年02月10日
    瀏覽(13)
  • [STL-list]介紹、與vector的對(duì)比、模擬實(shí)現(xiàn)的迭代器問題

    [STL-list]介紹、與vector的對(duì)比、模擬實(shí)現(xiàn)的迭代器問題

    ?list的底層是 帶頭雙向鏈表 結(jié)構(gòu),雙向鏈表中每個(gè)元素存儲(chǔ)在互不相關(guān)的獨(dú)立節(jié)點(diǎn)中,在節(jié)點(diǎn)中通過指針指向其前一個(gè)元素和后一個(gè)元素。 與其他的序列式容器相比(array,vector,deque),list通常 在任意位置進(jìn)行插入、移除元素的執(zhí)行效率更好 list最大的缺陷是 不支持任意位

    2024年04月15日
    瀏覽(23)
  • 【c++迭代器模擬實(shí)現(xiàn)】

    【c++迭代器模擬實(shí)現(xiàn)】

    打怪升級(jí):第52天 什么是STL STL(standard template libaray-標(biāo)準(zhǔn)模板庫(kù)):是C++標(biāo)準(zhǔn)庫(kù)的重要組成部分,不僅是一個(gè)可復(fù)用的組件庫(kù),而且是一個(gè)包羅數(shù)據(jù)結(jié)構(gòu)與算法的軟件框架。 STL的版本 原始版本 Alexander Stepanov、Meng Lee 在惠普實(shí)驗(yàn)室完成的原始版本,本著開源精神,他們聲明允許

    2024年02月02日
    瀏覽(17)
  • 【C++】vector模擬實(shí)現(xiàn)+迭代器失效

    【C++】vector模擬實(shí)現(xiàn)+迭代器失效

    鐵汁們,今天給大家分享一篇vector模擬實(shí)現(xiàn) + 迭代器失效,來吧,開造?? 指向最后一個(gè)空間的下一個(gè)位置 ?? iterator _endofstorage 指向存儲(chǔ)第一個(gè)有效數(shù)據(jù)空間的位置 ?? iterator _start 指向存儲(chǔ)最后一個(gè)有效數(shù)據(jù)空間的下一個(gè)位置 ?? iterator _finish 在成員變量聲明處給缺省值,

    2024年02月21日
    瀏覽(86)
  • 【C++】STL——反向迭代器的模擬實(shí)現(xiàn):迭代器適配器

    【C++】STL——反向迭代器的模擬實(shí)現(xiàn):迭代器適配器

    反向迭代器的使用相信大家都已經(jīng)比較熟悉了,那我們這篇文章具體講什么呢? ??,這篇文章我們重點(diǎn)來講一下 反向迭代器的模擬實(shí)現(xiàn) 。 那為什么我們之前不和正向迭代器放在一塊講呢?為什么要等到我們講完了容器適配器再來講反向迭代器的模擬實(shí)現(xiàn)呢? 那這個(gè)問題我

    2024年02月08日
    瀏覽(21)
  • 【C++】STL反向迭代器模擬實(shí)現(xiàn),迭代器適配器,迭代器類型簡(jiǎn)單介紹

    【C++】STL反向迭代器模擬實(shí)現(xiàn),迭代器適配器,迭代器類型簡(jiǎn)單介紹

    本篇主要講反向迭代器的模擬實(shí)現(xiàn)。 能夠加深各位對(duì)泛型的理解。 前面我那篇string介紹里面已經(jīng)提到過反向迭代器是啥了,如果點(diǎn)進(jìn)來的同學(xué)還不知道,可以看看:[string介紹](https://blog.csdn.net/m0_62782700/article/details/130796914? spm=1001.2014.3001.5501) 迭代器,可以在不暴露底層實(shí)現(xiàn)細(xì)

    2024年02月16日
    瀏覽(31)
  • [ C++ ] STL---反向迭代器的模擬實(shí)現(xiàn)

    [ C++ ] STL---反向迭代器的模擬實(shí)現(xiàn)

    目錄 前言: 反向迭代器簡(jiǎn)介 list反向迭代器的模擬實(shí)現(xiàn) ?反向迭代器的模擬實(shí)現(xiàn)(適配器模式) SGI版本STL反向迭代器源碼 STL庫(kù)中解引用操作與出口設(shè)計(jì) 適配list的反向迭代器 適配vector的反向迭代器 反向迭代器 是一種特殊類型的迭代器,它可以 逆向遍歷容器中的元素 ,與正向

    2024年04月15日
    瀏覽(20)
  • 【C++模擬實(shí)現(xiàn)】list的模擬實(shí)現(xiàn)

    作者:愛寫代碼的剛子 時(shí)間:2023.9.3 前言:本篇博客關(guān)于list的模擬實(shí)現(xiàn)和模擬實(shí)現(xiàn)中遇到的問題 list模擬實(shí)現(xiàn)的部分代碼 list模擬實(shí)現(xiàn)中的要點(diǎn) const_iterator的實(shí)現(xiàn) 我們選擇使用模版參數(shù),復(fù)用iterator的類,設(shè)置三個(gè)模版參數(shù): templateclass T,class Ref,class Ptr 并且 typedef __list_iter

    2024年02月09日
    瀏覽(25)
  • [C++歷練之路]優(yōu)先級(jí)隊(duì)列||反向迭代器的模擬實(shí)現(xiàn)

    [C++歷練之路]優(yōu)先級(jí)隊(duì)列||反向迭代器的模擬實(shí)現(xiàn)

    W...Y的主頁(yè) ??? 代碼倉(cāng)庫(kù)分享?? ??前言: 在C++的宇宙中,優(yōu)先隊(duì)列似乎是一座巨大的寶庫(kù),藏匿著算法的珍寶。而就在這片代碼的天空下,我們不僅可以探索優(yōu)先隊(duì)列的神奇,還能夠揭開反向迭代器的神秘面紗。讓我們一同踏入這個(gè)編程的探險(xiǎn)之旅,在這里,我們將用C

    2024年02月04日
    瀏覽(23)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包