智能指針shared_ptr

auto_ptr由於它的破壞性複製語義,無法滿足標準容器對元素的要求,因而不能放在標準容器中;如果我們希望當容器析構時能自動把它容納的指針元素所指的對象刪除時,通常採用一些間接的方式來實現,顯得比較繁瑣。boost庫中提供了一種新型的智能指針shared_ptr,它解決了在多個指針間共享對象所有權的問題,同時也滿足容器對元素的要求,因而可以安全地放入容器中。

當出現以下情況時應該優先考慮使用shared_ptr:
1.有多個使用者共同使用同一個對象,而沒有一個明顯的擁有者。
2.一個對象的複製操作很昂貴。
3.要把指針存入標準庫容器。
4.要傳送對象到庫或從庫獲取對象,而這些對象沒有明確的所有權。
5.當管理需要特殊清除方式的資源時,這時可以通過定製shared_ptr的刪除器
來實現。

template<class Other> explicit shared_ptr(Other *ptr);
這個構造函數獲得給定指針ptr的所有權。構造後引用計數設爲1,構造完成後將獲得一個跟ptr指向相同對象的shared_ptr。

template <class Y,class D> shared_ptr(Y* p,D d);

這個構造函數帶有兩個參數。第一個是shared_ptr將要獲得所有權的那個資源,第二個是shared_ptr被銷燬時負責釋放資源的一個對象,被保存的資源將以d(p)的形式傳給那個對象。因此p的值是否有效取決於d。如果引用計數器不能分配成功,shared_ptr拋出一個類型爲std::bad_alloc的異常。

shared_ptr(const shared_ptr& sp);
這個複製構造函數可以方便使用一個shared_ptr構造另外一個shared_ptr,原有shared_ptr中保存的資源將被新構造的shared_ptr所共享,引用計數加1.

shared_ptr& operator=(const shared_ptr& r);                                                                                               

賦值操作共享r中的資源,並停止對原有資源的共享。賦值操作不會拋出異常。

void reset();                                                                                                                             

reset函數用於停止對保存指針的所有權的共享。共享資源的引用計數減一。

T* get() const;                                                                                                                           

get函數是當保存的指針有可能爲空時(這時 operator*operator-> 都會導致未定義行爲)獲取它的最好辦法。注意,你也可以使用隱式布爾類型轉換來測試 shared_ptr 是否包含有效指針。這個函數不會拋出異常。

shared_ptr帶來的兩個問題:
1.體積問題
因爲shared_ptr需要進行引用計數,所以它需要額外的內存空間來保存當前內存資源的引用數,這使得一個shared_ptr指針將佔用40個字節的內存空間,是一個普通指針所佔用內存空間的整整10倍。
2.性能問題
一方面,因爲引用技術,shared_ptr需要在運行時對引用計數進行管理和維護,這樣就必然需要消耗額外的計算資源,影響程序的性能。另一方面,shared_ptr使用了大量的虛函數,虛函數的使用也帶來了一定的性能損失。

shared_ptr所管理的資源的清理工作都是由刪除器(deleter)來完成的。

輕量級的智能指針:unique_ptr

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章