STL與泛型編程第二周學習筆記——Boolan

在完成了STL與泛型編程第一周的學習之后,有一些總結和心得在這里通過學習筆記的方式分享出來,筆記我是跟著老師在視頻中所講的內容按照順序記錄的,也不能說是流水賬,對課程中的一些問題還是添加了自己的理解和分析,供也在學習C++的小伙伴用作學習交流,如有理解不到位的地方,歡迎批評指正。

上周對于STL,老師做了一個大概的介紹,本周接著上周的內容繼續學習了分配器以及各類容器的結構與分類。

一.OOP與GP的區別

OOP(Object-Oriented programming)企圖將datas和methods關聯在一起

GP(Generic Programming)卻是將datas和methods分開來,如下圖所示:


采用GP,Containerns和Algorithms兩個團隊可以閉門造車,其間以Iterator溝通即可。Algorithms通過Iterators確定操作范圍,并通過Iterators取用Container中的元素。

二.特化(Specialization)和偏特化(Partial Specialization)

C++源碼中運用了大量的操作符重載(Operator Overloading)以及模板(Templates),操作符重載的相關規則這里就不再贅述,模板的運用分為類模板(Class Templates)、函數模板(Function Templates)和成員模板(Member Templates),之前的課程有詳細講過,老師也進行了復習,這里也不再贅述。

我的理解是,特化就是泛化的反面,常規的模板都是泛化的,所謂特化,就是當模板替代類型中的一個類型有它特有的處理方法時,我們可以將template< >中的內容抽離出來,即為這個類型定義它特有的方法,如下代碼所示:


偏特化分為個數上的偏和范圍上的偏。

個數上的偏很好理解,就是具有多個模板參數時,將一部分模板參數特化,其他模板參數保持泛化,如下代碼所示:


這里值得注意的是,特化部分參數只能從左至右特化,也就是說,不能第一個模板參數泛化,而將第二個模板參數特化。

我理解的范圍上的偏就是模板參數的類型是一個指針,那么模板參數所代表的類型就是這個指針所指向的類型。如下代碼所示:


這里值得注意的是,該指針指向什么由程序員自己定義。

三.分配器(allocators)

分配器最重要的兩個函數:allocate()和deallocate()

VC6所附的標準庫,其分配器的實現只是以::operator new()和::operator delete()來完成allocate()和deallocate(),并沒有任何特殊的設計。


而operator new()和operator delete()本質上還是調用基本的內存分配函數malloc()和內存釋放函數free():


BC++與VC6一樣,最終還是調用malloc()和free(),并且也是分配512ints,但是分配多少內存就要還多少內存,因此其接口設計非常不利于直接使用。


G2.9并沒用使用分配器allocator,而創造了另一個分配器alloc,


alloc的實現如下圖所示:


用鏈表的方式來分配內存,盡量減少調用malloc的次數,這樣程序運行效率更高,節省了額外的開銷。

但是之后的G4.9并沒有使用這種高效率的alloc分配器(原因不得而知),而是改用了new_allocator分配器,這又與之前提到的VC/BC一致了,本質上還是調用malloc和free。但是G4.9所附的標準庫中,有許多extention allocators,其中_pool_alloc就是G2.9中的alloc

四.容器——結構與分類

先來一張老師整理出的各種容器類型和所占字節數的圖:


1.容器list

List其實是一個環狀雙向鏈表,用雙向指針串起來,如下圖所示:


List的iterator是一個類,G2.9中,這個類與list是包含關系。


這里值得注意的是,除了array和vector之外,所有容器的iterator都必須是class


之前說到過GP的好處就是將data和algorithm分開,那么iterator就是它們之間的橋梁,算法提出的問題,iterator要必須都能回答,這是iterator必須遵循的原則。

Iterators的五個associated types:

①Iterator_category()分類

②Difference_type()距離

③Value_type()指向值的類型

④Reference

⑤Pointer

后面兩個目前還未使用。

萃取機(Iterator Traits)用以分離class iterators(直接問)和non-class iterators(間接問)

加入中間層traits,利用偏特化回答non-class類型


2.容器vector

Vector是一種單向開口先進后出的容器,它所占用的是連續內存空間,因此它不能原地擴充,一旦空間不夠,它必須尋找新的空間擴充,并且二倍增長,整個搬離到新開辟的兩倍空間。


Vector靠3根指針控制整個容器:


因其是占用連續內存空間,所以它的iterator不必設計成class

3.容器array

Arry跟vector一樣,也是占用連續的內存空間,其iterator是native pointer


4.容器forward_list

Forward_list是一種線狀單向串列,與雙向鏈表list差不多


最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容