C 迭代器iterator的实现原理
在經典的設計模式中,有一種迭代器模式,定義為:提供一個對象來順序訪問聚合對象中的一系列數據,而不暴露聚合對象的內部表示。
迭代器的主要優點如下:
訪問一個聚合對象的內容而無須暴露它的內部表示。
遍歷任務交由迭代器完成,這簡化了聚合類。
它支持以不同方式遍歷一個聚合,甚至可以自定義迭代器的子類以支持新的遍歷。
增加新的聚合類和迭代器類都很方便,無須修改原有代碼。
封裝性良好,為遍歷不同的聚合結構提供一個統一的接口。
使用過STL的童鞋就知道,迭代器是STL使用最多的技術;那么迭代器具體是怎么實現的呢?本文來討論一下迭代器的原理和相關實現。
1. list類
首先,我們簡單的模擬一個單項鏈表,這個鏈表可以往表頭插入數據,并且返回表頭。
1.1 ListItem
首先,我們需要一個ListItem表示每個鏈表節點,這個聲明如下:
namespace?BH {template<typename?T>class?ListItem;template<typename?T>std::ostream&?operator<<(std::ostream&?out,?ListItem&?d);template<typename?T>class?ListItem{public:ListItem(const?T&?t)?:?Data(t),?Next(nullptr)?{}ListItem(T&&?t)?:?Data(std::forward(t)),?Next(nullptr)?{}template<typename...?Types>ListItem(Types&&...?args)?:?Data(std::forward(args)...),?Next(nullptr)?{}void?setnext(ListItem*?n){Next?=?n;}ListItem*?next(){return?Next;}friend?std::ostream&?operator<<?(std::ostream&?out,?ListItem&?d);private:ListItem*?Next;T*?Data;};template<typename?T>std::ostream&?operator<<(std::ostream&?out,?ListItem&?d){out?<<?d.Data;return?out;} }首先這里構造函數:
支持普通構造。
支持移動函數。
支持參數完美轉發。
友元operator<<,支持數據輸出。
對于移動函數可以參考:nktype="2" hasload="1" style="margin: 0px; padding: 0px; color: rgb(87, 107, 149); text-decoration-line: none; -webkit-tap-highlight-color: rgba(0, 0, 0, 0); cursor: pointer; max-width: 100%; box-sizing: border-box !important; overflow-wrap: break-word !important;">C 移動函數原理淺析。
1.2 list類
這個類實現一個鏈表,支持簡單的插入,并且返回頭部節點。
namespace?BH {template<typename?T>class?list{public:list()?noexcept?:?Head(nullptr)?{}void?push(const?T&?t){ListItem*?Data?=?new?ListItem(t);Data->setnext(Head);Head?=?Data;}void?push(T&&?t){ListItem*?Data?=?new?ListItem(t);Data->setnext(Head);Head?=?Data;}template<typename...?Types>void?emplace(Types&&...?args){ListItem*?Data?=?new?ListItem(std::forward(args)...);Data->setnext(Head);Head?=?Data;}ListItem*?front(){return?Head;}private:ListItem*?Head;}; }如上,為了演示,這個類實現的很簡單,只支持push,和front兩個操作。
2. iterator
使用過STL都知道,iterator主要是用來遍歷容器中的數據節點,那么上面這個list,我們的主要功能是能夠不用在外部知道list的實現原理,使用iterator來遍歷數據。
所以iterator的主要功能有:
支持 ,遍歷元素。
支持*,取元素程序。
支持->,指針操作。
支持==和!=操作,比較iterator是否到了結尾。
所以這個實現可以如下:
namespace?BH {template?<typename?T>class?ListIter{public:using?value_type?=?T;using?reference?=?T?&?;using?const_referenct?=?const?T&;using?pointer?=?T?*?;using?const_pointor?=?const?T*;using?size_type?=?size_t;using?difference_type?=?ptrdiff_t;ListIter(pointer?p?=?nullptr)?:?Iter(p)?{}bool?operator==(const?ListIter&?rhs)?const?noexcept{return?Iter?==?rhs.Iter;}bool?operator!=(const?ListIter&?rhs)?const?noexcept{return?Iter?!=?rhs.Iter;}ListIter&?operator (){Iter?=?Iter->next();return?*this;}ListIter&?operator (int){value_type?tmp?=?*this;&*this;return?tmp;}reference?operator*(){return?*Iter;}pointer?operator->(){return?Iter;}private:pointer?Iter;}; }3. 使用
接下來,我們看一下這個iterator如何使用:
int?main(int?args,?char*?argv[]) {BH::list<std::string>?l;l.push(std::string("hello"));l.push("world");l.push("abcd");l.push("efg");l.push("kmm");BH::ListIter<BH::ListItem<std::string>>?iter(l.front());BH::ListIter<BH::ListItem<std::string>>?end;while?(iter?!=?end){std::cout?<<?*iter?<<?std::endl;iter;}return?0; }總結
以上是生活随笔為你收集整理的C 迭代器iterator的实现原理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 无锡消防备案查询(无锡消防备案)
- 下一篇: 根据字符串自动构造对应类