1.源代碼分布
標(biāo)準(zhǔn)庫(kù)STL的文件位置蹬竖,與所采用的編譯器有關(guān):
(1)Visual C++:...\include ? (例如?D:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include)
(2)GNU C++:...\4.9.2\inlcude
2.OOP(Object-Oriented programming) VS GP(Generic programming)
OOP企圖將datas和methods關(guān)聯(lián)在一起
這里的list不能使用::sort()排序缤言,這是因?yàn)?:sort()算法設(shè)計(jì)中的Iterator必須是RandomAccessIterator彪置,而list并不是一個(gè)連續(xù)空間退腥,在內(nèi)存中它是由指針一個(gè)一個(gè)串起來(lái)惕稻,不能使用指針加法減法蔗衡。因此list不能使用::sort()排序纤虽。
GP卻是將datas和methods分開(kāi)來(lái)逼纸,兩者之間通過(guò)迭代器聯(lián)系在一起堆生。
兩者分開(kāi)的優(yōu)點(diǎn):
(1)Containers和Algorithms團(tuán)隊(duì)可各自閉門(mén)造車蔗怠,其間以Iterator溝通即可渔工;
(2)Algorithms通過(guò)Iterators確定操作范圍,并通過(guò)Iterators取用Container元素。
補(bǔ)充:
所有的algorithms杨何,最終設(shè)計(jì)元素本身的操作谋国,無(wú)非就是比大小近弟。比如說(shuō)重新定義max函數(shù)二鳄,根據(jù)字符長(zhǎng)度來(lái)比大小赴涵,我們就必須重寫(xiě)一個(gè)比較函數(shù)。
3.源代碼閱讀
基礎(chǔ):
(1)Operator Overloading 操作符重載
(2)Templates 模板
3.1操作符重載订讼、模板髓窜、特化和偏特化
這部分內(nèi)容在之前額課程中已經(jīng)講過(guò),不再贅述。
3.2分配器
分配器(Allocator)是容器管理內(nèi)存的工具寄纵,在容器申請(qǐng)內(nèi)存空間上起作用鳖敷。
分配器在底層實(shí)現(xiàn)上通過(guò)operator new()和operator delete()來(lái)完成內(nèi)存分配和釋放,而operator new()和operator delete()實(shí)際上是通過(guò)調(diào)用malloc()和free()函數(shù)來(lái)實(shí)現(xiàn)操作程拭。
operator new()和operator delete()的源代碼如下:
3.2.1 VC6的allocator
VC6所附的標(biāo)準(zhǔn)庫(kù)定踱,其allocator實(shí)現(xiàn)如下()
3.2.2 BC5的allocator
BC5所附的標(biāo)準(zhǔn)庫(kù),其allocator實(shí)現(xiàn)如下()
3.2.3 G2.9的allocator
G2.9所附的標(biāo)準(zhǔn)庫(kù)恃鞋,其allocator實(shí)現(xiàn)如下()
3.2.4 G4.9的allocator
G4.9所附的標(biāo)準(zhǔn)庫(kù)崖媚,其allocator實(shí)現(xiàn)如下:
由以上各編譯器中allocator的源代碼可以看出,無(wú)論是VC山宾、BC還是GNU的版本中分配器實(shí)際上是通過(guò)operator new和operator delete來(lái)調(diào)用malloc和free來(lái)管理內(nèi)存至扰。
但是在GNU2.9中鳍徽,容器實(shí)際使用的并非是allocator资锰,而是alloc,如下圖所示阶祭。
alooc的最終實(shí)現(xiàn)內(nèi)存管理也是通過(guò)malloc和free绷杜,但是可以避免其他額外開(kāi)銷,比如cookie濒募,實(shí)現(xiàn)過(guò)程如下:
(1)設(shè)計(jì)了16條鏈表鞭盟,每條鏈表負(fù)責(zé)某種特定大小的區(qū)塊,比如第0條鏈表負(fù)責(zé)8個(gè)字節(jié)大小的區(qū)塊瑰剃,第1條負(fù)責(zé)16個(gè)字節(jié)齿诉,以此類推,即(標(biāo)號(hào)數(shù)+1)*8晌姚;
(2)容器的元素大小都會(huì)調(diào)整到8的倍數(shù)粤剧,比如50的會(huì)調(diào)整到56,然后交給第6條鏈表負(fù)責(zé)挥唠;
(3)分配器查看鏈條有沒(méi)有掛內(nèi)存塊抵恋,如果沒(méi)有,向操作系統(tǒng)要內(nèi)存宝磨,得到的內(nèi)存塊除了頭尾有cookie弧关,中間的每一小塊內(nèi)存都不帶cookie;
實(shí)現(xiàn)過(guò)程示意圖如下圖所示:
在GNU4.9版本以后唤锉,分配器也直接調(diào)用了operator new來(lái)分配內(nèi)存世囊,之前2.9中的alloc放入了extention allocators中,也就是__pool_alloc窿祥,如下圖所示:
3.3容器的結(jié)構(gòu)與分類
課件里面將容器的結(jié)構(gòu)和分類講得很清楚株憾,具體如下圖所示:
3.4 容器list
3.4.1 list
G2.9的list:
G4.9的list:
3.4.2 list的iterator
G2.9的iterator:
G4.9相較于G2.9:
模板參數(shù)只有一個(gè)(易理解);
node結(jié)構(gòu)有其parent壁肋;
node的成員的type較精確号胚;
具體如下圖所示: