2005-12-03

終於搞懂 smart pointer

最近開始使用boost 的smart pointer. 倒也不是第一次使用smart pointer. 但是經過這次的研究, 發現原來我之前用smart pointer沒用到精隨.... 現在一般的smart poiner都是實作reference counter的機制來管理pointer的生命週期. 以前也有用過reference counter的機制..但是並沒有和smart pointer的機制結合在一起. 變成當我想要作share的時候, 我才使用smart pointer...一般的時候..就是使用標準C/C++ pointer..然後自己管理這個pointer的生命( 自己呼叫delete ptr或是如果有reference counter機制, 就呼叫 ptr->Release()之類) 如下

class Obj: RefCounted{
};

Obj *pOldSchool = get_ptr_from_somewhere();
pOldSchool->AddRef();
....//do somthing
//delete the ptr
pOldSchool->Release();

------------------------------------------------------
以前大概對Reference counter的機制也不是很完整的理解吧. (老實說一開始我對這樣的架構不是很習慣...會覺得..為何new完物件之後, 卻要呼叫Release來刪除呢...腦筋一時轉不過來, 覺得new/delete是天生一對) 現在懂得使用smart pointer之後, 其實就可以這樣寫

smart_ptr< Obj > pNewSchool = get_ptr_from_somewhere();
...//do something
-------------------------------------------------------
smart pointer 會管理pointer的生命. 這樣就可以只要負責new就好, smart pointer會去管理刪除的問題了..所以其實物件不管會不會跟其他物件share, 用smart pointer都可以得到好處. 比如說class有要物件的pointer, 宣告成smart pointer, 這樣在destructor就不用去處理該pointer.不過smart pointer使用上要注意A reference B, 同時B reference A的問題. 想想若是沒有好好研究boost 的smart pointer, 可能一時也不會發覺會有這個問題. (因為目前公司的專案有用開發自己的smart pointer, 在使用過程並未想到有這個問題說..)
現在全面把程式改成使用 smart pointer. 把"delete xxx"的code想辦法拿掉..希望不會走火入魔...Orz

boost smart pointer不錯的入門說明

3 意見:

fr3@K 提到...

看到這篇還真擔心你會走火入魔...

給你個遲來了一年半的建議, 先從了解兩個 smart pointer 著手:
1. std::auto_ptr, 以及
2. boost::shared_ptr

std::auto_ptr 是非常 light weight 的 smart pointer, 許多情況下既夠用又好用. 譬如指標的所有權轉移, 以及區域性的指標回收. 也是我最常用的 smart pointer. 最大缺點是不能放在容器裏面.

需要 reference counting 的時候, 才用到 boost::shared_ptr. 缺點是除了 reference counting 本身的負擔之外, 在 shared_ptr 內還加了層鎖, 以確保 reference counting 的機制是 thread-safe. 可是它的保護只限於 reference counting 機制, 並不包含被管理的物件本身. 換句話說, 如果被管理的物件需要 thread-safety, 外部還是要加一層鎖. (結果就是兩個鎖 XD)

其他的 smart pointer 可以有時間再慢點玩也不遲.

codefield 提到...

我目前都是用boost::intrusive_ptr
物件本身就已經具有reference counter的機制了, 因此使用auto_ptr似乎也得不到特別的好處...

不過intrusive_ptr並未納入TR1, 也許以後之後我會改採shared_ptr

CxxlMan 提到...

http://cxxlman.sitesled.com/index.html

這裏提供更強的 Smart_Ptr