C++11 新特性之智慧指標

usher2007發表於2016-08-14

前四篇在這裡:
C++11新特性之新型別與初始化:  http://blog.jobbole.com/102728/
C++11新特性之型別推斷與型別獲取:  http://blog.jobbole.com/104559/
C++11新特性之lambda:http://blog.jobbole.com/104548/
C++11新特性之容器相關特性: http://blog.jobbole.com/104563/

這是C++11新特性介紹的第五部分,涉及到智慧指標的相關內容(shared_ptr, unique_ptr, weak_ptr)。
不想看toy code的讀者可以直接拉到文章最後看這部分的總結。

shared_ptr

shared_ptr 基本用法

shared_ptr採用引用計數的方式管理所指向的物件。當有一個新的shared_ptr指向同一個物件時(複製shared_ptr等),引用計數加1。當shared_ptr離開作用域時,引用計數減1。當引用計數為0時,釋放所管理的記憶體。

這樣做的好處在於解放了程式設計師手動釋放記憶體的壓力。之前,為了處理程式中的異常情況,往往需要將指標手動封裝到類中,通過解構函式來釋放動態分配的記憶體;現在這一過程就可以交給shared_ptr去做了。

一般我們使用make_shared來獲得shared_ptr。

shared_ptr 和 new

shared_ptr可以使用一個new表示式返回的指標進行初始化。

但是,不能將一個new表示式返回的指標賦值給shared_ptr。

另外,特別需要注意的是,不要混用new和shared_ptr!

上面的程式片段會輸出:

可以看到,第二次process p6時,shared_ptr的引用計數為1,當離開process的作用域時,會釋放對應的記憶體,此時p6成為了懸掛指標。

所以,一旦將一個new表示式返回的指標交由shared_ptr管理之後,就不要再通過普通指標訪問這塊記憶體!

shared_ptr.reset

shared_ptr可以通過reset方法重置指向另一個物件,此時原物件的引用計數減一。

shared_ptr deleter

可以定製一個deleter函式,用於在shared_ptr釋放物件時呼叫。

unique_ptr

unique_ptr基本用法

unique_ptr對於所指向的物件,正如其名字所示,是獨佔的。所以,不可以對unique_ptr進行拷貝、賦值等操作,但是可以通過release函式在unique_ptr之間轉移控制權。

unique_ptr 作為引數和返回值

上述對於拷貝的限制,有兩個特殊情況,即unique_ptr可以作為函式的返回值和引數使用,這時雖然也有隱含的拷貝存在,但是並非不可行的。

這裡的std::move函式,以後再單獨具體細說^_^

unique_ptr deleter

unique_ptr同樣可以設定deleter,和shared_ptr不同的是,它需要在模板引數中指定deleter的型別。好在我們有decltype這個利器,不然寫起來好麻煩。

weak_ptr

weak_ptr一般和shared_ptr配合使用。它可以指向shared_ptr所指向的物件,但是卻不增加物件的引用計數。這樣就有可能出現weak_ptr所指向的物件實際上已經被釋放了的情況。因此,weak_ptr有一個lock函式,嘗試取回一個指向物件的shared_ptr。

總結

  1. shared_ptr採用引用計數的方式管理所指向的物件。
  2. shared_ptr可以使用一個new表示式返回的指標進行初始化;但是,不能將一個new表示式返回的指標賦值給shared_ptr。
  3. 一旦將一個new表示式返回的指標交由shared_ptr管理之後,就不要再通過普通指標訪問這塊記憶體。
  4. shared_ptr可以通過reset方法重置指向另一個物件,此時原物件的引用計數減一。
  5. 可以定製一個deleter函式,用於在shared_ptr釋放物件時呼叫。
  6. unique_ptr對於所指向的物件,是獨佔的。
  7. 不可以對unique_ptr進行拷貝、賦值等操作,但是可以通過release函式在unique_ptr之間轉移控制權。
  8. unique_ptr可以作為函式的返回值和引數使用。
  9. unique_ptr同樣可以設定deleter,需要在模板引數中指定deleter的型別。
  10. weak_ptr一般和shared_ptr配合使用。它可以指向shared_ptr所指向的物件,但是卻不增加物件的引用計數。
  11. weak_ptr有一個lock函式,嘗試取回一個指向物件的shared_ptr。

完整程式碼詳見smart_pointer.cpp

打賞支援我寫出更多好文章,謝謝!

打賞作者

打賞支援我寫出更多好文章,謝謝!

任選一種支付方式

C++11 新特性之智慧指標 C++11 新特性之智慧指標

相關文章