日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 人文社科 > 生活经验 >内容正文

生活经验

设计1.0 -- iterator 和const_iterator底层的模拟实现

發(fā)布時(shí)間:2023/11/27 生活经验 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计1.0 -- iterator 和const_iterator底层的模拟实现 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文概要:

本文主要是模擬實(shí)現(xiàn)STL中迭代器和const迭代器的,主要闡述的一個(gè)問(wèn)題就是,為什么我們?cè)谠O(shè)計(jì)迭代器的時(shí)候需要使用三個(gè)模板參數(shù)呢

在設(shè)計(jì)迭代器的時(shí)候,我們有下面的代碼

#include<iostream>
using namespace std;template<class T>
struct _ListNode
{_ListNode<T>* _next;_ListNode<T>* _prev;T _data;_ListNode(T d = 0):_data(d), _next(NULL), _prev(NULL){}
};//這個(gè)T標(biāo)記的是維護(hù)的數(shù)據(jù)類(lèi)型,Ref是引用,這個(gè)引用是對(duì)數(shù)據(jù)的引用,就是這里面data的引用
//Ptr是指針,這個(gè)指針也是指向數(shù)據(jù)data的指針這兩個(gè)模板類(lèi)型我們可以在
//List這個(gè)類(lèi)里面使用,因?yàn)樵诰帉?xiě)List_Iterator的時(shí)候,會(huì)經(jīng)常使用Ref和Ptr
template<class T, class Ref, class Ptr>
class List_Iterator
{typedef _ListNode<T> Node;typedef List_Iterator<T, Ref, Ptr> Self;   //這個(gè)地方寫(xiě)的 有點(diǎn)失誤了,就是把List_Iterator的單詞寫(xiě)錯(cuò)了
public:List_Iterator(Node* it):_it(it){}//List_Iterator& operator++()Self& operator++(){_it = _it->_next;return *this;}Self operator++(int)    //注意前置++返回的是引用,而后置++返回的是Self{Node* tmp = _it;_it = _it->_next;return tmp;}//T& operator*()Ref operator*(){return _it->_data;}bool operator!=(const Self& it){return _it != it._it;    //一開(kāi)始寫(xiě)這個(gè)!=運(yùn)算符重載的時(shí)候也出現(xiàn)了錯(cuò)誤,就是我一開(kāi)始是拿this和&it比//這顯然是不對(duì)的,兩個(gè)迭代器不可能是相等的,所以這個(gè)時(shí)候應(yīng)該是拿//這兩個(gè)迭代器所指向的內(nèi)容來(lái)比較,就是那他們的成員變量來(lái) 進(jìn)行比較才正確}private:Node* _it;
};//這里我們需要做一個(gè)修改就是,我們需要把這個(gè)鏈表定義成一個(gè)雙向的有頭的循環(huán)鏈表
//這個(gè)工作就是要在構(gòu)造函數(shù)的時(shí)候去做了
//所以這里_tail就不需要了//有頭結(jié)點(diǎn),_head維護(hù)了一個(gè)頭結(jié)點(diǎn),但是這個(gè)節(jié)點(diǎn)不放置任何的數(shù)據(jù),因?yàn)檫@樣在后面的增刪查改的時(shí)候使用的時(shí)候會(huì)非常的方便
template<class T>
class _List
{typedef _ListNode<T> Node;public:typedef List_Iterator<T, T&, T*> Ierator;//const迭代器typedef List_Iterator<T, const T&, const T*> Const_Ierator;_List():_head(new Node)   //這里報(bào)了一個(gè)錯(cuò)誤就是,沒(méi)有合適的構(gòu)造函數(shù)可以使用,原因是我上面寫(xiě)_ListNode的時(shí)候//傳參了,但是這里沒(méi)有傳參數(shù),所以我上面的額時(shí)候把傳遞的參數(shù)默認(rèn)為d = 0這個(gè)時(shí)候就算是我不傳遞參數(shù)//也沒(méi)有什么問(wèn)題了//  , _tail(_head){_head->_next = _head;_head->_prev = _head;}Node* begin(){if (_head->_next == _head)   //這里做了一個(gè)判斷就是當(dāng)我們的鏈表是空的時(shí)候,就不能直接返回next{return NULL;}return _head->_next;}Node* end(){if (_head->_next == _head){return NULL;}return _head;}void Pushback(const T& data){Node* cur = new Node(data);cur->_prev = _head->_prev;_head->_prev = cur;cur->_next = _head;cur->_prev->_next = cur;}void Print(){Const_Ierator it = begin();   //這個(gè)原因是,我們的begin不是 const的,但是我們的const_ietator是const的while (it != end()){cout << *it << endl;it++;}}
private:Node* _head;
//  Node* _tail;
};void TestList()
{_List<int> l;l.Pushback(0);   //一開(kāi)始的時(shí)候,我這里設(shè)置的這個(gè)參數(shù)是引用,這個(gè)時(shí)候是辯不過(guò)的,因?yàn)槲覀兊?是在常量區(qū)的l.Pushback(1);l.Pushback(2);/*_List<int>::Ierator it = l.begin();cout << *it << endl;++it;cout << *it << endl;++it;cout << *it << endl;*/_List<int>::Ierator it = l.begin();*it = 5;l.Print();}

這里想重點(diǎn)比較一下普通迭代器和const迭代器,這里我們想看我們的普通迭代器的定義,

template<class T, class Ref, class Ptr>
class List_Iterator
{typedef _ListNode<T> Node;typedef List_Iterator<T, Ref, Ptr> Self;   //這個(gè)地方寫(xiě)的 有點(diǎn)失誤了,就是把List_Iterator的單詞寫(xiě)錯(cuò)了
public:List_Iterator(Node* it):_it(it){}//List_Iterator& operator++()Self& operator++(){_it = _it->_next;return *this;}Self operator++(int)    //注意前置++返回的是引用,而后置++返回的是Self{Node* tmp = _it;_it = _it->_next;return tmp;}//T& operator*()Ref operator*(){return _it->_data;}bool operator!=(const Self& it){return _it != it._it;    //一開(kāi)始寫(xiě)這個(gè)!=運(yùn)算符重載的時(shí)候也出現(xiàn)了錯(cuò)誤,就是我一開(kāi)始是拿this和&it比//這顯然是不對(duì)的,兩個(gè)迭代器不可能是相等的,所以這個(gè)時(shí)候應(yīng)該是拿//這兩個(gè)迭代器所指向的內(nèi)容來(lái)比較,就是那他們的成員變量來(lái) 進(jìn)行比較才正確}private:Node* _it;
};

這里只是一個(gè)普通的迭代器的實(shí)現(xiàn),一開(kāi)始我一直疑惑的一個(gè)問(wèn)題就是,為什么這里在設(shè)計(jì)的時(shí)候需要設(shè)計(jì)三個(gè)模板參數(shù) 呢,因?yàn)槭菫榱藢?shí)現(xiàn)迭代器的復(fù)用,這個(gè)時(shí)候還是需要看一下我們的list中對(duì)于迭代器的使用

class _List
{typedef _ListNode<T> Node;public:typedef List_Iterator<T, T&, T*> Ierator;//const迭代器typedef List_Iterator<T, const T&, const T*> Const_Ierator;_List():_head(new Node)   

這里我只截圖了迭代器的一部分,想看全部的可以從上面來(lái)看,這里需要定義一個(gè)普通的迭代器的時(shí)候,使用typedef List_Iterator

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

因?yàn)槲覀冊(cè)趌ist中使用的時(shí)候是按照下面的形式進(jìn)行組織的

typedef List_Iterator<T, const T&, const T*> Const_Ierator;

所以在上面的那個(gè)Ref operator*()里面 返回值就變成了const的,這個(gè)時(shí)候const_iterator所指向的內(nèi)容就不可變了

總結(jié)

以上是生活随笔為你收集整理的设计1.0 -- iterator 和const_iterator底层的模拟实现的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。