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