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