2011年5月5日 星期四

Boost 之 smart pointer

C++最令人苦惱的地方,不外乎就是語言特性太複雜( OO 及 Generic Programming 等等),以及缺乏自動記憶體管理。通常在寫C++時,我們會使用 RAII (Resource Acquisition Is Initialization) 這個 idiom (慣用手法) 來管理記憶體,也就是在物件的 constructor 中申請資源,然後在 destructor 釋放。但這僅僅於物件是建立在 stack 中 (Local variable)可行,若物件是建立於 heap 中,則 destructor 永遠不會被呼叫,除非我們手動 delete 它。

為了更方便開發者管理記憶體,smart pointer 一直是C++陣營一直在探討的議題之一。而 C++98 中提供一個 smart point:auto_ptr
auto_ptr 的 constructor 接受一個由 new operator 或是 object factory 所建立出的指標為參數,擁有這個指標所指的物件,並透過 override operator* 及 operator-> 來使其用起來像是一個真的指標。在 auto_ptr 退出其 scope 後,destructor 自然會被呼叫,而釋於資源。

auto_ptr 解決了記憶體管理的問題,但它還不夠好用,最大的問題就是它對物件所有權的管理策略屬於 Destructive Copy,也就是一次只能有一個 auto_ptr 持有一個物件,禁止共享。

std::auto_ptr<int> ptr1 ( new int (2) );
std::auto_ptr<int> ptr2;
ptr2 = ptr1 ; // transfer ownership from ptr1 to ptr2

Boost.smart_ptr 基於 auto_ptr 擴充了六種適合不同需求所用的 smart pointers:
  1. scoped_ptr:類似 auto_ptr,但物件所有權無法轉移,因此同 auto_ptr,也無法被放到 STL container 中。另外,正如其名,我們只能在某個 scope 中使用它。
  2. scoped_array:scoped_ptr 的 array 版本,即內部是使用 new [ ] 及 delete [ ] 而非 new 與 delete。
  3. shared_ptr:是最類似 pointer 的 smart pointer,也是 Boost 中最有價值,最有用的組件。它實作了 reference count 機制,因此可以任何地方被 copy 及 assign value,當 reference count 為 0 時才會 delete 它。另外,shared_ptr 可以被使用於 STL container 中。
  4. shared_array:shared_ptr 的 array 版本。
  5. weak_ptr:一個用來協助 shared_ptr 的 smart pointer,通常它與 shared_ptr 共享同一個物件,但不會增加 reference count,因為它沒有 override operator* 及 operator->,因此也不會使用它來操作物件。它主要提供 use_count( ) 及 expired( ) 來回報 shared_ptr 的 reference count 以及內部指標是否有效等資訊。
  6. intrusive_ptr:一種侵入式的 smart pointer,由於 Boost 目前已不建議使用,因此也不多作介紹。
詳細使用方法可參考 http://www.boost.org/doc/libs/1_46_1/libs/smart_ptr/smart_ptr.htm

如果可以,請多多使用 shared_ptr 及 shared_array

沒有留言: