设计1.0 -- iterator 和const_iterator底层的模拟实现
本文概要:
本文主要是模擬實(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)題。
- 上一篇: 摩尔庄园精灵怎么放生?
- 下一篇: STL模拟实现1.0 -- list和i