boost筆記:智能指針--概述

boost::scoped_ptr<T>

  scoped_ptr用於確保能夠正確地刪除動態分配(new)的對象。scoped_ptr永遠不能被複制或被賦值!因此scoped_ptr擁有它所指向的資源的所有權,並永遠不會放棄這個所有權。scoped_ptr構造時即擁有動態分配資源的所有權,直到使用reset()函數重新指定新的資源,或者超出作用域而釋放所有權。
  scoped_ptr的實現和std::auto_ptr非常類似,都是利用了一個棧上的對象去管理一個堆上的對象,從而使得堆上的對象隨着棧上的對象銷燬時自動刪除。不同的是,scoped_ptr有着更嚴格的使用限制——不能拷貝。這就意味着:scoped_ptr指針是不能轉換其所有權的。
  boost::scoped_ptr的特點:
  1. 不能轉換所有權
    scoped_ptr所管理的對象生命週期僅僅侷限於一個區間(該指針所在的"{}"之間),無法傳到區間之外,這就意味着scoped_ptr對象是不能作爲函數的返回值的(std::auto_ptr可以)。
  2. 不能共享所有權
    這點和std::auto_ptr類似。這個特點一方面使得該指針簡單易用。另一方面也造成了功能的薄弱——不能用於stl的容器中。
  3. 不能用於管理數組對象
    由於scoped_ptr是通過delete來刪除所管理對象的,而數組對象必須通過delete []來刪除,因此scoped_ptr是不能管理數組對象的,如果要管理數組對象需要使用boost::scoped_array類。
  boost::scoped_ptr的使用場景:
  1. 在可能有異常拋出的作用域裏使用指針
  2. 函數裏有幾條控制路徑,指針在操作作用域後需要釋放
  3. 動態分配對象的生存期應被限制於特定的作用域內
  4. 異常安全非常重要時(始終如此!)

boost::scoped_array<T>

  scoped_array用於確保能夠正確地刪除動態分配(new[])的數組對象。
  scoped_array與scoped_ptr均不能共享所有權,不能轉移所有權。不同的是scoped_array提供了operator[]來模仿一個裸數組。

  scoped_array是比普通的動態分配數組更好用。它處理了動態分配數組的生存期管理問題,就如scoped_ptr管理對象指針的生存期一樣。只有當你需要確保數組的大小是固定的時候,才使用boost::scoped_array來替代std::vector。

boost::shared_ptr<T>

  boost::shared_ptr的管理機制其實並不複雜,就是對所管理的對象進行了引用計數,當新增一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數加一;減少一個boost::shared_ptr對該對象進行管理時,就將該對象的引用計數減一,如果該對象的引用計數爲0的時候,說明沒有任何指針對其管理,才調用delete釋放其所佔的內存。
  boost::shared_ptr的特點:
  1. 在內部維護一個引用計數器, 當有一個指針指向這塊內存區域是引用計數+1, 反之-1, 如果沒有任何指針指向這塊區域,引用計數器爲0,釋放內存區域。
  2. 可以共享和轉移所有權。
  3. 可以被標準庫的容器所使用
  4. 不能用於管理數組對象(用boost::share_array代替)
  5. 它是線程安全的。
  boost::shared_ptr的使用場景:
  1. 避免對shared_ptr所管理的對象的直接內存管理操作,以免造成該對象的重釋放
  2. shared_ptr並不能對循環引用的對象內存自動管理(這點是其它各種引用計數管理內存方式的通病)。
  3. 不要構造一個臨時的shared_ptr作爲函數的參數。
  4. 用於標準模板庫的容器中

boost::shared_array<T>

  shared_array用於確保能夠正確的刪除通過new[]分配的動態數組對象,與boost::scoped_array不同,shared_array具有提供拷貝構造和賦值運算,具有共享和轉移所有權。並提供了比較運算符,可以被標準模板庫中的容器使用。
  因爲它是通過引用計數實現,故對循環引用的實例將無法正確回收。

  std::vector<boost::shared_ptr>是boost::shared_array的替代方案,後者雖然比前者具有更重的責任,但是比前者靈活的多。

boost::intrusive_ptr<T>

  intrusive_ptr一種“侵入式”的引用計數指針,它實際並不提供引用計數功能,而是要求被存儲的對象自己實現引用計數功能,並提供intrusive_ptr_add_ref和intrusive_ptr_release函數接口供intrusive_ptr調用。如果編譯器支持參數相關查找,可把這兩個函數定義在其參數所在的命名空間,否則需定義在boost命名空間內。

  有兩種方法實現intrusive_ptr_add_ref和intrusive_ptr_release接口:

  1. 自定義的類從boost提供的引用計數器基類boost::intrusive_ptr_base<T>繼承
  2. 類似com接口指針等,自己實現引用計數功能,並特例化intrusive_ptr_add_ref和intrusive_ptr_release這兩個接口。
  如果T*可以隱式轉換爲U*,那麼intrusive_ptr<T>也可隱式轉換爲intrusive_ptr<U>。

  使用boost::intrusive_ptr的場景:

  1. 一些現有的框架或操作系統提供了具有嵌入式引用計數的對像,如com對象
  2. intrusive_ptr和其相應的原始指針指向的內存是一樣的
  3. 可以從任意T*類型的原始指針構造intrusive_ptr<T>
  一般情況下,如果能使用boost::shared_ptr就不要使用boost::intrusive_ptr。




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