STL原始碼剖析

2022-09-14 14:18:14 字數 2280 閱讀 7532

花了兩天時間略讀了一下《stl原始碼分析》,看了個大體,對於細節並沒有深究。之所以想翻翻這本書,主要是想看看stl中的特性、介面卡的具體實現。看完之後收穫還是蠻大的,模板的各種組合讓我眼前一亮,下面大概總結一些內容。

1.記憶體分配:sgi記憶體分配採用兩級實現,對於大記憶體塊的申請(大於128k)由第一級實現,第一級實現較簡單,直接呼叫malloc和free。對於小於128k的記憶體請求,由第二級實現。第二級使用了記憶體池,維護了一些鍊錶,分別指向不同大小的空閒記憶體塊,這些記憶體塊都是8的倍數的大小,分別是8k,16k,24k,...,128k。分配記憶體時,根據請求大小找到相應鍊錶的表頭,然後從表頭摘取乙個結點塊,**的時候也是從表頭插入。第二級記憶體分配的實現方式跟linux作業系統的空閒記憶體管理很相似,不過記憶體**的時候有區別,linux記憶體管理還涉及到空閒塊的合併。

2.迭代器:要設計一種迭代器,必須對容器的具體實現有豐富的了解,所以把迭代器的實現交給容器的設計者,這樣就可以是容器的實現細節得以封裝,所以每一種stl容器都提供了專屬的迭代器。迭代器中的end()具體指向了哪個位置?對於vector這種由連續記憶體塊來實現的容器,end()指向陣列之後的乙個位置。而對於list,map,set這種由」結點「實現的容器,會有專門的乙個結點,該結點含有一些重要的資訊,比如指向開頭結點的指標。為什麼有些迭代器只能是向前的?因為其容器的內部實現決定了它的迭代器只能是前向的,比如單向鍊錶的迭代器當然只能是向前的了。

3.容器:deque的結構挺複雜的,使用了分段陣列,並使用了乙個map陣列來對映不同分段陣列的位址,通過封裝,使其使用起來就像是個連續的陣列一樣。stack和queue的內部結構使用的是deque。vector容器增長的平均時間複雜度是o(1)。具體計算,大家可以自己想想。

4.traits:c++的特性讓我見識了c++抽象的強大,通過增加一層抽象,使問題的解決變得很微妙。這部分主要利用了模板的型別推斷能力。通過偏特化,能夠粹取出類型別和原始指標的特性。印象很深的乙個例子是advance函式。

templateinline 

void __advance(inputiterator&i, distance n, input_iterator_tag)

template

inline

void __advance(forwarditerato&i, distance n, fowrd_iterator_tag)

template

inline

void __advance(bidirectionaliterator&i, distance n, bidirectional_iterator_tag)

else

}template

linue

void __advance(randomaccessiterator&i, distance n, random_access_iterator_tag)

view code

實現了四個不同的函式過載,再增加乙個上層函式advance(),粹取出迭代器的型別,並呼叫相應的__advance版本。

templateinline 

void advance(inputiterator&i, distance n)

view code

5.介面卡:介面卡的實現主要是在內部包含了乙個物件,在外面展示不同的介面,內部實際上還是間接使用了其所包含的物件。為什麼說為了讓乙個函式物件在stl是可適配的?因為在外層類中要使用到內部包含型別的某些」特性「,比如bind1st,就要使用到內部二元函式仿函式的first_argument_type。所以為了能夠被適配,一般都要繼承unary_function和binary_function。

6.採用輔助函式:我們知道使用模板類宣告乙個物件,需要給出具體的型別,有時手動地給出具體型別會很麻煩,那麼有沒有辦法讓編譯器自動推導出具體的型別呢?這裡使用了」增加一層抽象「,使用模板函式,模板函式具有自動推導的功能,利用模板函式推導出來的型別來具現模板類。比如下面的例子。

template

class binder1st : public unary_function

typename operation::result_type

operator()(const typename operation::second_argument_type& x)const

};template

inline binder1st

bind1st(const operation& op, const t&x)

view code

嗯,就先總結到這些吧。其他的一些東西要麼之前了解得比較熟了,那麼印象不是很深刻,就不寫出來了。

STL原始碼剖析

這兩天略讀完了 stl原始碼剖析 之所以是略讀,就是只看大體,不講具現 這個詞在 深度探析c 物件模型 中比較多 已經看過好幾本c 的書了,感覺c 本身設計的博大精深,而c 編譯器就更是乙個神奇的東西,換句話說,你永遠不知道c 編譯器揹著你做了哪些出乎你意料的事 不扯遠了 我主要是想看stl容器的具...

STL原始碼剖析

這兩天略讀完了 stl原始碼剖析 之所以是略讀,就是只看大體,不講具現 這個詞在 深度探析c 物件模型 中比較多 已經看過好幾本c 的書了,感覺c 本身設計的博大精深,而c 編譯器就更是乙個神奇的東西,換句話說,你永遠不知道c 編譯器揹著你做了哪些出乎你意料的事 不扯遠了 我主要是想看stl容器的具...

STL 原始碼剖析 functional

其中比較有意思的兩個函式模板,mem fun與mem fun ref,目的是用於將成員函式轉換為可用的函式物件。具體實現如下所示 非stl原始碼 class kvalshow public void show void setval int n bool sort fun const kvalsho...