smart_ptr庫(kù)是Boost中比較小的庫(kù)之一,也是實(shí)際應(yīng)用中使用最頻繁的庫(kù)之一。下面結(jié)合這段時(shí)間對(duì)它的學(xué)習(xí)了解,梳理Boost/smart_ptr庫(kù)的知識(shí)構(gòu)架。
Boost/smart_ptr庫(kù)主要目的是為了解決C++中最讓人頭疼的部分:內(nèi)存泄漏。自從C++引入異常機(jī)制以來(lái),內(nèi)存泄漏一直圍繞著C++程序員,每個(gè)C++都小心翼翼地防止著,但內(nèi)存泄漏就像空氣中的NIHI病毒一樣,讓人防不勝防。如是,各種各樣的智能指針開(kāi)始出現(xiàn)了,最終也就誕生了偉大的Boost/smart庫(kù)。
經(jīng)過(guò)千萬(wàn)次的錘煉,Boost/smart庫(kù)已經(jīng)逐漸完美了,已被C++ 0x接受。估計(jì)再向前發(fā)展的空間比較小。
Boost/smart庫(kù)主要構(gòu)建了以下幾種智能指針:
1.scoped_ptr
2.scoped_array
3.shared_ptr
4.shared_array
5.weap_ptr
6.intrusive_ptr
下面分別詳細(xì)介紹每種smart_ptr的用途。
1. scoped_ptr
scoped_ptr是根據(jù)C++標(biāo)準(zhǔn)庫(kù)中的auto_ptr改進(jìn)過(guò)來(lái)的。Auto_ptr的一個(gè)很大的缺陷就是在賦值的時(shí)候會(huì)轉(zhuǎn)移操作權(quán)限,而scoped_ptr不會(huì)發(fā)生這樣的情況,原因在于scoped_prt根本就不允許賦值操作:
private:
scoped_ptr(scoped_ptr const &);
scoped_ptr & operator=(scoped_ptr const &);
使用scope_ptr需要注意的地方:
a. scope_ptr只能從new操作符、0以及auto_ptr構(gòu)造。
b. operator*操作時(shí)做好先判斷ptr是否為0.如果ptr=0,*操作會(huì)導(dǎo)致未定義的行為
使用方法和auto_ptr一樣,只是不允許賦值操作。示例:
2. scoped_array
scoped_array是scoped_ptr的數(shù)組形式的版本。scoped_array之所以是一個(gè)單獨(dú)的類(lèi)而不是scoded_ptr的一個(gè)特化,這是因?yàn)樵幊碳夹g(shù)無(wú)法區(qū)分指向單個(gè)對(duì)象的指針和指向數(shù)組的指針,不管如何努力,還是沒(méi)有人能夠發(fā)現(xiàn)一種可靠的能區(qū)分這兩種形式指針的方法,這是因?yàn)閿?shù)組太容易退化成指針了而且沒(méi)有任何信息表明它指向數(shù)組。最后只能我們用scoped_array單獨(dú)處理指向數(shù)組的指針了,正如delete無(wú)法取代delete[]一樣。
使用示例:
3. shared_ptr
就我個(gè)人看來(lái),shared_ptr是最有使用價(jià)值的智能指針了,它采用了非侵入式的引用技術(shù)技術(shù),幾乎可以取代平時(shí)工作中可能導(dǎo)致內(nèi)存泄漏的普通指針。另外它還提供了可自定義的析構(gòu)方法,這么一來(lái),它幾乎可以安全管理所有資源了(包含文件,句柄等等)。值得欣慰的是,shared_ptr和shared_array已經(jīng)被C++標(biāo)準(zhǔn)委員會(huì)接受,C++ 0x中應(yīng)該就會(huì)包含這個(gè)讓大家使用很方便的智能指針了。
shared_ptr解決了共享對(duì)象什么時(shí)候刪除的問(wèn)題。讓C++程序員不用再想盡方法刪除共享對(duì)象了。
使用shared_ptr需要注意的地方:
a. shared_ptr可以從裸指針、另一個(gè)shared_ptr、std::auto_ptr或者weak_ptr構(gòu)造而來(lái)
b. shared_ptr的引用計(jì)數(shù)器來(lái)自堆分配。所以通過(guò)裸指針或者std::auto_ptr構(gòu)造時(shí)。可能會(huì)因?yàn)槎芽臻g不足而拋出std::bad_alloc的異常(非常小的幾率)
c. 從只能指針weak_ptr構(gòu)造shared_ptr使weak_ptr的使用具有了線程安全。這里需要注意的是,如果weak_ptr懸空的話(huà),那么shared_ptr將拋出一個(gè)bad_weak_ptr的異常。
d. shared_ptr構(gòu)造的時(shí)候,允許傳遞釋放所存儲(chǔ)對(duì)象的方法,這就讓我們可以用shared_ptr管理除了指針外的其他設(shè)備,示例:
e. shared_ptr可以用在C++標(biāo)準(zhǔn)容器中
f. 最后附上shared_ptr的設(shè)計(jì)源碼,方面查閱
4. shared_array
shared_array是shared_ptr的數(shù)組形式,他們的關(guān)系就像scoped_ptr和scoped_array的關(guān)系。shared_array的接口了shared_ptr的接口非常相似,但shared_array重載了下標(biāo)運(yùn)算符{},且不支持自定義的析構(gòu)方式。
5. weap_ptr
智能指針weap_ptr是shared_ptr的觀察者,它不會(huì)影響shared_ptr所共享資源的所有權(quán)。為什么需要weap_ptr呢?因?yàn)樵谠S多情況下,需要觀察某個(gè)共享資源但是又不想接受它的所有權(quán),例如為了打破循環(huán)依賴(lài)關(guān)系、為了觀察某個(gè)共享資源而不想接受它的所有權(quán)或者為了避免懸空指針時(shí),就需要使用weap_ptr。
暫時(shí)有點(diǎn)難懂,留下它的設(shè)計(jì)文檔以后需要的時(shí)候再研究。
6. intrusive_ptr
intrusive_ptr是shared_ptr的侵入式版本了,因?yàn)槭褂妙l率很低,暫時(shí)不做說(shuō)明。
總結(jié):Boost.Smart庫(kù)是一個(gè)非常非常優(yōu)秀的庫(kù),是一個(gè)無(wú)論怎么評(píng)價(jià)都不為過(guò)的優(yōu)秀庫(kù),值得學(xué)習(xí),值得廣泛應(yīng)用。
Copyright © 天邊藍(lán)