C++?STL反向迭代器的實(shí)現(xiàn)
反向迭代器其實(shí)就行對(duì)正向迭代器進(jìn)行封裝,源生迭代器,為了實(shí)現(xiàn)運(yùn)算符的結(jié)果不同,正向迭代器也對(duì)源生迭代器進(jìn)行了封裝。
反向迭代器的適配器,就是 Iterator是哪個(gè)容器的迭代器,reverse_iterator < Iterator >就可以 適配出哪個(gè)容器的反向迭代器。復(fù)用的體現(xiàn)。
反向迭代器適配器結(jié)構(gòu):
template <class Iterator, class Ref, class Ptr>
class reverse_iterator
{
typedef reverse_iterator<Iterator, Ref, Ptr> self;
public:
// 重載運(yùn)算符函數(shù)
private:
Iterator _it;
};
源碼容器獲取迭代器時(shí)具體情況,如圖:

我們以為的情況:

這是源碼里的實(shí)現(xiàn)的大概情況,begin()與rend()對(duì)稱,end()與rbegin()對(duì)稱。這與我們想的不一樣,所以反向迭代器適配器內(nèi)部實(shí)現(xiàn)的也有所不一樣。例如:
如果我們按照源碼的思路寫,反向迭代器里封裝了一個(gè)正向迭代器_it,正常的++,–等操作只需要調(diào)用_it的–,++運(yùn)算符重載函數(shù)即可。除了,operator*需要特寫,如下代碼:
Ref operator*()
{
//正常思路
//return *_it;
// 源碼思路
Iterator prev = _it;
return *--prev;
}
正常情況是解引用迭代器,但是源碼的思路是往后一個(gè)位置的迭代器才是。這也是因?yàn)閞begin,和rend實(shí)現(xiàn)的原因?qū)е碌摹?/p>
適配出來的反向迭代器其用法和正向迭代器一樣;
反向迭代器根正向迭代器區(qū)別就是++、–的方向是相反的所以反向迭代器封裝正向迭代器即可,重載控制++、–的方向。
源碼的設(shè)計(jì)追求對(duì)稱,我們?cè)O(shè)計(jì)可以不按源碼走,在容器實(shí)現(xiàn)rbegin(),rend()時(shí),要按照反向迭代器的設(shè)計(jì)風(fēng)格去實(shí)現(xiàn)。
list完整樣例:
1、反向迭代器適配器
// Iterator是哪個(gè)容器的迭代器,reverse_iterator<Iterator>就可以
// 適配出哪個(gè)容器的反向迭代器。復(fù)用的體現(xiàn)
template <class Iterator, class Ref, class Ptr>
class reverse_iterator
{
typedef reverse_iterator<Iterator, Ref, Ptr> self;
public:
reverse_iterator(Iterator it)
:_it(it)
{}
Ref operator*()
{
//正常思路
//return *_it;
Iterator prev = _it;
return *--prev;
}
Ptr operator->()
{
return &operator*();
}
self& operator++()
{
--_it;
return *this;
}
self& operator--()
{
++_it;
return *this;
}
bool operator!= (const self& rit)
{
return _it != rit._it;
}
private:
Iterator _it;// 封裝任何類型的正向迭代器
};
二、list 正向迭代器
// iterator -> 類去分裝節(jié)點(diǎn)指針,重載*、++ 等運(yùn)算符,讓它們像指針一樣使用
template<class T,class Ref,class Ptr>
class _list_iterator
{
public:
typedef _list_iterator < T, Ref,Ptr> self;
typedef ListNode<T> Node;
_list_iterator( Node* x)
:_node(x)
{}
// ++it
self& operator++()
{
_node = _node->_next;
return *this;
}
// it++
self operator++(int)
{
self tmp(*this);
_node = _node->_next;
return tmp;
}
// --it
self& operator--()
{
_node = _node->_pre;
return *this;
}
// it--
self operator--(int)
{
self tmp(*this);
_node = _node->_pre;
return tmp;
}
//*
Ref operator*()
{
return _node->_data;
}
//->
Ptr operator->()
{
return &(_node->_data);
}
//!=
bool operator!=(const self& x)
{
return _node != x._node;
}
//==
bool operator==(const self& x)
{
return _node == x._node;
}
Node* _node;
};
三、 list容器
注意:這里只涉及反向迭代器的內(nèi)容
template<class T>
class list
{
public:
typedef ListNode<T> Node;
typedef _list_iterator<T, T&, T*> iterator;
typedef _list_iterator<T, const T&, const T*> const_iterator;
typedef reverse_iterator<const_iterator, const T&, const T*> const_reverse_iterator;
typedef reverse_iterator<iterator, T&, T*> reverse_iterator;
reverse_iterator rbegin()
{
return reverse_iterator(end());
}
const_reverse_iterator rbegin()const
{
return const_reverse_iterator(end());
}
reverse_iterator rend()
{
return reverse_iterator(begin());
}
const_reverse_iterator rend()const
{
return const_reverse_iterator(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);
}
list()
{
_head= new Node();
_head->_next = _head;
_head->_pre = _head;
}
void push_back(const T&x)
{
Node* newnode = new Node(x);
Node* tail = _head->_pre;
newnode-> _pre = tail;
tail->_next = newnode;
newnode->_next = _head;
_head->_pre = newnode;
}
private:
Node* _head;// 頭結(jié)點(diǎn)指針
};
測(cè)試代碼:
void test11()
{
BBQ::list<int> L1;
L1.push_back(1);
L1.push_back(2);
L1.push_back(3);
reverse_print_list(L1);
}
到此這篇關(guān)于C++ STL反向迭代器的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)C++ STL反向迭代器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
VC中CWinThread類以及和createthread API的區(qū)別分析
這篇文章主要介紹了VC中CWinThread類以及和createthread API的區(qū)別分析,較為詳細(xì)的講述了CWinThread類的原理,并以實(shí)例形式對(duì)AfxBeginThread函數(shù)的內(nèi)部實(shí)現(xiàn)進(jìn)行了解釋說明,需要的朋友可以參考下2014-10-10
利用C++實(shí)現(xiàn)通訊錄管理系統(tǒng)的完整代碼
通訊錄是一個(gè)可以記錄親人、好友信息的工具,下面這篇文章主要給大家介紹了關(guān)于利用C++實(shí)現(xiàn)通訊錄管理系統(tǒng)的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-06-06
c語言讀取obj文件轉(zhuǎn)換數(shù)據(jù)的小例子
c語言讀取obj文件轉(zhuǎn)換數(shù)據(jù)的小例子,需要的朋友可以參考一下2013-03-03
C++遞歸實(shí)現(xiàn)螺旋數(shù)組的實(shí)例代碼
這篇文章主要介紹了C++遞歸實(shí)現(xiàn)螺旋數(shù)組的實(shí)例代碼,代碼簡單易懂,非常不錯(cuò),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-04-04

