軟體工程與哲學

Smart Pointer

商業,創業,業務,職涯,美食,葡萄酒,閱讀,網路科技。
從 Larry 創業以及商業的經驗,希望以白話的口吻,介紹給大家這個商業的世界。
FB粉絲頁 Larry的午茶時光
IG Larry的午茶時光 歡迎大家追蹤~

想整理 smart pointer 這個 topic 很久了. 本篇主要 focus 在於 C++ STL 的 smart pointer, 尤其是 C++11 所提供的新 smart pointer 支援, 而不去考慮其他 library 所提供的 smart pointer (ex. Boost).

在 C++11 之前, 我們習慣的 smart pointer 是 std::auto_ptr<T>. 所以本篇會先 review 一下 auto_ptr 的用法及用途. 接下來會討論一下 C++11 introduce 的 std::unique_ptr, std::shared_ptr, std::weak_ptr.

std::auto_ptr<T> 最大也是最基本的特性是他所指向的 memory (或是換句話說: 他所管理的 resource), 會隨著 auto_ptr 生命的結束而結束. 另外 copy constructor 和 assignment operator 的 assigner 會把他管理的 resource 轉移到 assignee. std::auto_ptr<T>::reset method 則會把他之前管理的 resource 釋放, reset 到新的一塊 memory. 以上可以避免 new 與 delete 不成對出現. 程式執行期間 pointer 被更動, memory 的 ownership 不清, 等等造成 memory leak 的問題. 然而, auto_ptr 有個很大的問題是他的 copy constructor 和 assignment operator 會將 assigner 中所含的 resource 清空, 所以他不是真正的 copy/assign, 在很多 case 下會有 run-time assertion 或各種當機 (ex. 一個 auto_ptr vector 作 stl sort ).

在新的 C++ standard 中 auto_ptr 已經被 deprecated 了. 取而代之的是 unique_ptr. unique_ptr 取消了 ambiguous 的 copy constructor 跟 assignment operator (compile 就不會過), 而用 std::move 明確的來執行 ownership 的轉移.


在真的需要 copy operation 的時候可以使用 std::shared_ptr. 在真正 allocate memory 或作 copy 時 ( copy constructor / assignment ) shared_ptr 中的 reference counter 會加 1. 當其中一個 shared_ptr 生命結束時 reference counter 會減 1, reference counter 會減到 0 時資源真正被釋放 ( 擁有同一資源的 shared_ptr 共用同一 reference counter ).

weak_ptr 基本上是與 shared_ptr 搭配使用. 他的目的是將 monitor 值與資源管理分開. 例如:

shared_ptr a( new int( 10 ) );
weak_ptr b = a;

//.... some processing

// now "a" does not necessarily have resource, so "c" may be null.
shared_ptr c = b.lock();

針對以上例子, 如果不用 weak_ptr, 而在同樣位置要確認 “a” 的值的話, 勢必要留一個 shared_ptr 下來. 如果系統有 N 個地方需要取這個值, reference count 就會變成 >N. 此非 shared_ptr 的設計理念 (需要真正 keep 住此 pointer 的地方 reference count才需增加). 另外當一個 shared_ptr 的 reference count 很大時, 也會無法管理.

最後, unique_ptr 的使用時機應該在於系統內有 “unique” 性質的物件或是資料, 正因為有unique特性, 其他模組要使用此物件或資料時才會需要”轉移”. 當然絕大部分的狀況是多處要同時 access 同一物件, 此時就要使用 shared_ptr.

larry 20130304 updates: 最近發現一篇關於 C++ 11 smart pointer 不錯的文章
http://eli.thegreenplace.net/2012/06/20/c11-using-unique_ptr-with-standard-library-containers/

商業,創業,業務,職涯,美食,葡萄酒,閱讀,網路科技。
從 Larry 創業以及商業的經驗,希望以白話的口吻,介紹給大家這個商業的世界。
FB粉絲頁 Larry的午茶時光
IG Larry的午茶時光 歡迎大家追蹤~

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *