欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

【C++】list類模擬實現-創(chuàng)新互聯

list
  • 一、list類實現準備
    • 1.1 list的節(jié)點類
    • 1.2 list類的成員變量
  • 二、迭代器實現????
    • 2.1 正向迭代器
    • 2.2 反向迭代器
  • 三、list類接口的實現
    • 3.1 構造函數
    • 3.2 begin()和end()
    • 3.3 插入
    • 3.4 頭插和尾插
    • 3.5 刪除
    • 3.6 頭刪和尾刪
    • 3.7 clear()和析構
    • 3.8 拷貝構造
      • 3.8.1 現代寫法
    • 3.9 賦值拷貝
      • 3.9.1 現代寫法
    • 3.10 初始化沖突問題

在鄭州等地區(qū),都構建了全面的區(qū)域性戰(zhàn)略布局,加強發(fā)展的系統(tǒng)性、市場前瞻性、產品創(chuàng)新能力,以專注、極致的服務理念,為客戶提供做網站、網站建設 網站設計制作按需設計網站,公司網站建設,企業(yè)網站建設,高端網站設計,營銷型網站,成都外貿網站制作,鄭州網站建設費用合理。一、list類實現準備

首先要知道list就是一個帶頭循環(huán)雙向鏈表,在博主以前的文章有過詳細講解順序表和鏈表超詳細大總結
現在我們首先就要實現每個節(jié)點的類:

1.1 list的節(jié)點類
templatestruct ListNode
	{ListNode(const T& val = T())
			: _prev(nullptr)
			, _next(nullptr)
			, _val(val)
		{}
		ListNode* _prev;
		ListNode* _next;
		T _val;
	};
1.2 list類的成員變量

list的成員變量只需要頭節(jié)點

typedef ListNodeNode;
private:
		Node* _head;
二、迭代器實現???? 2.1 正向迭代器

按照以前的思路寫迭代器如下:

templatestruct _list_iterator
	{typedef ListNodeNode;
		_list_iterator(Node* p)
		{	_p = p;
		}

		T& operator*()
		{	return _p->_val;
		}

		_list_iterator& operator++()
		{	_p = _p->_next;
			return *this;
		}

		_list_iterator& operator++(int)
		{	_list_iteratortmp(*this);
			_p = _p->_next;
			return tmp;
		}

		_list_iterator& operator--()
		{	_p = _p->_prev;
			return *this;
		}

		_list_iterator& operator--(int)
		{	_list_iteratortmp(*this);
			_p = _p->_prev;
			return tmp;
		}

		//end() 返回臨時變量具有常屬性 
		bool operator!=(const _list_iterator& it) const
		{	return _p != it._p;
		}

		bool operator!=(const _list_iterator& it) const
		{	return _p == it._p;
		}

		Node* _p;
	};

我們還有個迭代器叫做const迭代器,就是可以++,--,*,就是用的時候不能修改。也就是不能返回T&而是const T&
有人可能想實現一個const版本的重載:

const T& operator*() const
		{	return _p->_val;
		}

但現在我們的容器是const,傳的迭代器沒有變,想要修改還是可以。
為了解決這個問題,第一個方法是拷貝一份迭代器,換個名字,在使用上面的const版本*重載即可。但這樣就會造成代碼冗余。

所以我們可以這樣修改:

typedef _list_iteratoriterator;
typedef _list_iteratorconst_iterator;

傳入兩個模板參數,迭代器模板使用template
再把*重載改成:

Ref operator*()
		{	return _p->_val;
		}

雙模板參數迭代器實現如下:

templatestruct _list_iterator
	{typedef ListNodeNode;
		typedef _list_iteratoriterator;
		_list_iterator(Node* p)
		{	_p = p;
		}

		Ref operator*()
		{	return _p->_val;
		}

		iterator& operator++()
		{	_p = _p->_next;
			return *this;
		}

		iterator& operator++(int)
		{	_list_iteratortmp(*this);
			_p = _p->_next;
			return tmp;
		}

		iterator& operator--()
		{	_p = _p->_prev;
			return *this;
		}

		iterator& operator--(int)
		{	iterator tmp(*this);
			_p = _p->_prev;
			return tmp;
		}

		//end() 返回臨時變量具有常屬性 
		bool operator!=(const iterator& it) const
		{	return _p != it._p;
		}

		bool operator==(const iterator& it) const
		{	return _p == it._p;
		}

		Node* _p;
	};

但是我們可以發(fā)現還有一個問題:*重載如果是原生類型好說,但是對于自定義類型我們需要取出每一個對象就需要重載->
例如我們想要打印日期類的年月日,直接*取出的是節(jié)點。所以我們可以重載一個->拿到節(jié)點。

T* operator->()
	{return &_p->_val;
	}

打印年月日就可以這么寫:

list::iterator it = lt.begin();
while (it != lt.end())
{cout<< it->year<< it->month<< it->day<< endl;
	++it;
}

其實這里應該寫成it->->year,為了可讀性編譯器優(yōu)化省略了一個->。而且所有類型只要想重載->都會這樣省略。而重載->又會涉及到是否能修改的問題。所以再傳一個模板參數。

typedef _list_iteratoriterator;
typedef _list_iteratorconst_iterator;

對于迭代器:

Ptr operator->()
		{	return &_p->_val;
		}
2.2 反向迭代器

其實正向迭代器就是對Node* 指針的封裝,而反向迭代器就是正向迭代器的封裝。

反向迭代器的--就是正向迭代器的++。
而比較大的區(qū)別時反向迭代器的*重載取得不是當前位置,而是前一個位置的值。
在這里插入圖片描述
正向迭代器的開始就是反向迭代器的結束,正向迭代器的結束就是反向迭代器的開始。
代碼如下:

namespace yyh
{templatestruct reverse_iterator
	{typedef reverse_iteratoriterator;
		// 封裝正向迭代器
		reverse_iterator(Iterator it)
			: _it(it)
		{}

		Ref operator*()
		{	Iterator tmp = _it;
			return *--tmp;
		}

		Ptr operator->()
		{	Iterator tmp = _it;
			return &--tmp;
		}

		iterator& operator++()
		{	--_it;
			return *this;
		}

		iterator& operator++(int)
		{	iterator tmp(*this);
			--_it;
			return tmp;
		}

		iterator& operator--()
		{	++_it;
			return *this;
		}

		iterator& operator--(int)
		{	iterator tmp(*this);
			++_it;
			return tmp;
		}

		bool operator==(const iterator& it) const
		{	return _it == it._it;
		}

		bool operator!=(const iterator& it) const
		{	return _it != it._it;
		}

		Iterator _it;
	};
}
三、list類接口的實現 3.1 構造函數
_list_iterator(Node* p)
		{	_p = p;
		}
3.2 begin()和end()
iterator begin()
		{	return iterator(_head->_next);
		}

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

		const const_iterator begin() const
		{	return const_iterator(_head->_next);
		}

		const const_iterator end() const
		{	return const_iterator(_head);
		}
3.3 插入
iterator insert(iterator pos, const T& val)
		{	Node* cur = pos._p;
			Node* prev = cur->_prev;
			Node* newnode = new Node(val);
			cur->_prev = newnode;
			newnode->_next = cur;
			prev->_next = newnode;
			newnode->_prev = prev;
			return iterator(newnode);
		}
3.4 頭插和尾插
void push_back(const T& val)
		{	insert(end(), val);
		}

		void push_front(const T& val)
		{	insert(begin(), val);
		}
3.5 刪除
iterator erase(iterator pos)
		{	assert(pos != end());
			Node* prev = pos._p->_prev;
			Node* next = prev->_next->_next;
			delete pos._p;
			prev->_next = next;
			next->_prev = prev;
			return iterator(next);
		}
3.6 頭刪和尾刪
void pop_back()
		{	erase(--end());
		}

		void pop_front()
		{	erase(begin());
		}
3.7 clear()和析構
~list()
		{	clear();
			delete _head;
			_head = nullptr;
		}

		void clear()
		{	iterator it = begin();
			while (it != end())
			{		it = erase(it);
			}
		}
3.8 拷貝構造
list(const list& lt)
		{	// 先創(chuàng)建頭節(jié)點
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			const_iterator it = lt.begin();
			while (it != lt.end())
			{		push_back(*it);
				++it;
			}
		}

這里要注意先創(chuàng)建頭節(jié)點,再插入數據。

3.8.1 現代寫法
// 迭代器區(qū)間初始化
		templatelist(InputIterator first, InputIterator last)
		{	// 先創(chuàng)建頭節(jié)點
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			while (first != last)
			{		push_back(*first);
				++first;
			}
		}

		list(const list& lt)
		{	_head = new Node;// _head不能為nullptr,析構會解用
			_head->_next = _head;
			_head->_prev = _head;
			listtmp(lt.begin(), lt.end());
			swap(_head, tmp._head);
		}

這里如果給_head賦值為nullptr,后邊調用clear()會用到return iterator(_head->_next);,程序崩潰。

3.9 賦值拷貝
list& operator=(const list& lt)
		{	if (this != <)
			{		clear();
				for (auto& e : lt)
				{push_back(e);
				}
			}
			return *this;
		}
3.9.1 現代寫法
list& operator=(listlt)
		{	_head->_next = _head;
			_head->_prev = _head;
			swap(_head, lt._head);
			return *this;
		}
3.10 初始化沖突問題

當我們想用n個val初始化的時候:

list(size_t n, const T& val = T())
		{	_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			for (size_t i = 0; i< n; i++)
			{		push_back(val);
			}
		}

但是我們前面使用迭代器初始化:

templatelist(InputIterator first, InputIterator last)
		{	// 先創(chuàng)建頭節(jié)點
			_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			while (first != last)
			{		push_back(*first);
				++first;
			}
		}

當我們使用listlt(5, 1)時,此時我們就會傳到迭代器區(qū)間初始化,造成尋址錯誤。
解決方法:
重載一個int 類型的初始化函數:

list(size_t n, const T& val = T())
		{	_head = new Node;
			_head->_next = _head;
			_head->_prev = _head;
			for (size_t i = 0; i< n; i++)
			{		push_back(val);
			}
		}

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧

分享名稱:【C++】list類模擬實現-創(chuàng)新互聯
本文來源:http://aaarwkj.com/article36/jcgpg.html

成都網站建設公司_創(chuàng)新互聯,為您提供網站收錄、網頁設計公司、微信小程序做網站、移動網站建設網站設計公司

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯

成都網頁設計公司
日韩一二区不卡在线视频| 久久亚洲天堂色图不卡| 久久久亚洲成人国产av| 亚洲国产理论片在线观看| 先锋影音女同中文字幕| 亚洲精品国产av成人| 97国产超碰在线观看| 韩国午夜理伦三级好看| 欧美日韩国产这里只有精品| 国产日韩欧美亚洲中文国| 国产原创剧情免费观看av| 婷婷久久五月综合激情| 一二三四在线观看日本资讯| 日韩欧美一区二区狠狠插| 日本午夜理论视频在线播放 | 亚洲av日韩av高潮| 草逼免费在线观看视频| 亚洲中文永久免费视频| 日韩欧美亚洲一级黄片| 91久久精品国产免费一区| 精品人妻aⅴ一区二区| 国产一区二区高清不卡| 久久精品国产亚洲av波多| 超碰91人人草人人干| 国产伦理自拍视频在线观看| 99久久精品人妻少妇一| 午夜激情视频福利在线观看| 日韩国产传媒视频在线观看| 国产成人av在线观看| 久热伊人精品国产中文| 五月婷婷丁香花综合网| 亚洲精品国产自在现线| 青青草免费视频观看在线| 丁香六月色婷婷亚洲激情| 日本免费一区中文字幕| 欧美精品蜜桃激情一区久久| 最新国产激情福利网站| 亚洲精品亚洲一区亚洲二区| 正在播放蜜臀av在线| 日本免费观看一区久久| 怡红院怡春院视频免费看|