天天看點

C++ 智能指針的正确使用方式

文章目錄

    • 寫在前面
    • 一、unique_ptr
      • 1. 不支援複制和指派,隻支援移動
      • 2. 性能
    • 二、shared_ptr
      • 1. 支援複制,也支援移動
      • 2. 性能
    • 三、weak_ptr
    • 四、選擇哪種指針作為函數的參數

寫在前面

本文主要總結一下 C++ 智能指針的正确使用方式,以下内容主要是對下面參考連結的總結、轉載,文中的詳細解釋請參考原連結,如有侵權,請聯系删除。

參考連結:

[1] C++ 智能指針的正确使用方式 https://www.cyhone.com/articles/right-way-to-use-cpp-smart-pointer/

一、unique_ptr

我們大多數場景下用到的應該都是

unique_ptr

1. 不支援複制和指派,隻支援移動

unique_ptr

代表的是專屬所有權,即由

unique_ptr

管理的記憶體,隻能被一個對象持有。

是以,

unique_ptr

不支援複制和指派。如果想要把

w

複制給

w2

, 是不可以的。因為複制從語義上來說,兩個對象将共享同一塊記憶體。

是以,

unique_ptr

隻支援移動。

2. 性能

因為 C++ 的 zero cost abstraction 的特點,unique_ptr 在預設情況下和裸指針的大小是一樣的。

是以 記憶體上沒有任何的額外消耗,性能是最優的。

二、shared_ptr

在使用

shared_ptr

之前應該考慮,是否真的需要使用

shared_ptr

, 而非

unique_ptr

1. 支援複制,也支援移動

shared_ptr

代表的是共享所有權,即多個

shared_ptr

可以共享同一塊記憶體。

是以,從語義上來看,

shared_ptr

是支援複制的。s

hared_ptr

也支援移動。從語義上來看,移動指的是所有權的傳遞。

隻要将

new

運算符傳回的指針

p

交給一個 shared_ptr 對象“托管”,就不必擔心在哪裡寫

delete p

語句——實際上根本不需要編寫這條語句,托管

p

shared_ptr

對象在消亡時會自動執行delete p。

多個

shared_ptr

對象可以共同托管一個指針

p

,當所有曾經托管

p

shared_ptr

對象都解除了對其的托管時,就會執行

delete p

2. 性能

  • 記憶體占用高
  • 原子操作性能低
  • 使用移動優化性能

    shared_ptr 在性能上固然是低于 unique_ptr。而通常情況,我們也可以盡量避免 shared_ptr 複制。

三、weak_ptr

weak_ptr 是為了解決 shared_ptr 雙向引用的問題。

weak_ptr 不會增加引用計數,是以可以打破 shared_ptr 的循環引用。

通常做法是 parent 類持有 child 的 shared_ptr, child 持有指向 parent 的 weak_ptr。這樣也更符合語義。

四、選擇哪種指針作為函數的參數

很多時候,函數的參數是個指針。這個時候就會面臨選擇困難症,這個參數應該怎麼傳,應該是 shared_ptr,還是 const shared_ptr&,還是直接 raw pointer 更合适。

  1. 隻在函數使用指針,但并不儲存對象内容

    假如我們隻需要在函數中,用這個對象處理一些事情,但不打算涉及其生命周期的管理,也不打算通過函數傳參延長 shared_ptr 的生命周期。

    對于這種情況,可以使用 raw pointer 或者 const shared_ptr&。

    即:

void func(Widget*);
void func(const shared_ptr<Widget>&)
           

實際上第一種裸指針的方式可能更好,從語義上更加清楚,函數也不用關心智能指針的類型。

  1. 在函數中儲存智能指針

    假如我們需要在函數中把這個智能指針儲存起來,這個時候建議直接傳值。

這樣的話,外部傳過來值的時候,可以選擇 move 或者指派。函數内部直接把這個對象通過 move 的方式儲存起來。

這樣性能更好,而且外部調用也有多種選擇。

參考連結:

[1] C++ 智能指針的正确使用方式 https://www.cyhone.com/articles/right-way-to-use-cpp-smart-pointer/

c++
上一篇: jsp-jstl

繼續閱讀