筆者最近在分析stl系列原始碼,所取用的原始碼標準為sgi-stl 2.9.0。筆者並不打算詳細分析stl的內部資料結構,因為資料結構這個課程為大學所學,筆者並不打算當一次復讀機。
筆者個人認為分析stl原始碼最大的鐵板為迭代器,因為迭代器是stl容器和演算法兩大部件之間的橋梁,迭代器並不能單獨存在,它必須要依託特定的容器物件。依照筆者個人理解,容器主要提供可供操作的資料和物件,而演算法是對這組資料和物件的加工,比如說std::sort(); std::find();這兩個演算法需要一組資料,或者排序操作,或者查詢操作。例如 std::vectorvc; 需要去查詢這個容器裡面是否出現了乙個資料value,std::find(vc.begin(),vc.end(),value); *****==>個人覺得是演算法需要向容器要一組資料,告訴演算法這組資料的範圍。而這個範圍需要迭代器劃出。
言歸正傳,結合原始碼分析,我選取了std::list作為分析物件,重點講解list中的迭代器是如何當作橋梁使用的。
* list的node節點,這個節點中有乙個向前指和向後指向的指標,但是為什麼不是指向node???
* 卻是乙個指向為void的指標
template
struct __list_node
__list_iterator() {}
__list_iterator(const iterator& x) : node(x.node) {}
bool operator==(const self& x) const
bool operator!=(const self& x) const
reference operator*() const
#ifndef __sgi_stl_no_arrow_operator
pointer operator->() const
#endif /* __sgi_stl_no_arrow_operator */
self& operator++() ;
這樣,我們可以通過 traits::value_type 來獲得myiterator的value_type,於是我們把foo函式改寫成:
template //這裡的i可以是任意型別的迭代器
typename traits::value_type foo(i i)
然而,即使這樣,那個原生指標的問題仍然沒有解決,因為trait類一樣沒辦法獲得原生指標的相關資訊。於是我們祭出c++的又一件利器--偏特化(partial specialization):
template
class traits//注意 這裡針對原生指標進行了偏特化
;通過上面這個 traits的偏特化版本,我們陳述了這樣乙個事實:乙個 t* 型別的指標所指向的元素的型別為 t。
如此一來,我們的 foo函式就完全可以適用於原生指標了。比如:
int * p;
....
int i = foo(p);
traits會自動推導出 p 所指元素的型別為 int,從而foo正確返回。
過程:內嵌型別->traite類->模板偏特化=>可萃取原生指標的value type。
分析模式之分析
size medium color blue 可能有些人就會奇怪現在最熱的莫過於設計模式,而市面上關於設計模式的書層出不窮。但是我個人感覺設計模式是要看,但是你如果真正理解了分析模式那麼對於設計模式也就不難了。可以怎麼看分析模式是內涵而設計模式是外延而已。首先我先把我認為的分析模式闡述下 2.何為模...
迭代器失效小分析
stl中容器按儲存方式分為兩類 一是按陣列容器順序儲存的序列式容器 如 vector,deque 另一類是以不連續的節點形式儲存的容器 list set map 迭代器失效小例項 void printvector vector v cout endl void testvector 迭代器失效 對於...
Iterator迭代器簡略分析
iteratorit c.iterator 當在執行這行語句時,它是底層是怎麼樣子的?首先collectionextendsitrable,介面繼 承介面,而itrable中有乙個抽象方法,iteratoriterator 其返回值是iterator,iterator介面中有三個抽象方法,hasne...