天天看點

智能指針shared_ptr的用法

  為了解決C++記憶體洩漏的問題,C++11引入了智能指針(Smart Pointer)。

  智能指針的原理是,接受一個申請好的記憶體位址,構造一個儲存在棧上的智能指針對象,當程式退出棧的作用域範圍後,由于棧上的變量自動被銷毀,智能指針内部儲存的記憶體也就被釋放掉了(除非将智能指針儲存起來)。

  C++11提供了三種智能指針:std::shared_ptr, std::unique_ptr, std::weak_ptr,使用時需添加頭檔案<memory>。

  shared_ptr使用引用計數,每一個shared_ptr的拷貝都指向相同的記憶體。每使用他一次,内部的引用計數加1,每析構一次,内部的引用計數減1,減為0時,删除所指向的堆記憶體。shared_ptr内部的引用計數是安全的,但是對象的讀取需要加鎖。

shared_ptr的基本用法

初始化

  可以通過構造函數、std::make_shared<T>輔助函數和reset方法來初始化shared_ptr:

智能指針shared_ptr的用法
智能指針shared_ptr的用法

   注意,不能将一個原始指針直接指派給一個智能指針,如下所示,原因是一個是類,一個是指針。

  reset()有兩種操作。當智能指針中有值的時候,調用reset()會使引用計數減1.當調用reset(new xxx())重新指派時,智能指針首先是生成新對象,然後将就對象的引用計數減1(當然,如果發現引用計數為0時,則析構舊對象),然後将新對象的指針交給智能指針保管。

擷取原始指針  

指定删除器

  智能指針可以指定删除器,當智能指針的引用計數為0時,自動調用指定的删除器來釋放記憶體。std::shared_ptr可以指定删除器的一個原因是其預設删除器不支援數組對象,這一點需要注意。

  2. 使用shared_ptr需要注意的問題

  但凡一些進階的用法,使用時都有不少陷阱。

不要用一個原始指針初始化多個shared_ptr,原因在于,會造成二次銷毀,如下所示:

不要在函數實參中建立shared_ptr。因為C++的函數參數的計算順序在不同的編譯器下是不同的。正确的做法是先建立好,然後再傳入。

禁止通過shared_from_this()傳回this指針,這樣做可能也會造成二次析構。

避免循環引用。智能指針最大的一個陷阱是循環引用,循環引用會導緻記憶體洩漏。解決方法是AStruct或BStruct改為weak_ptr。

智能指針shared_ptr的用法
智能指針shared_ptr的用法
智能指針shared_ptr的用法
智能指針shared_ptr的用法
智能指針shared_ptr的用法
智能指針shared_ptr的用法