std::shared_ptr使用方法和注意事項


1.創建

有三種方式,分別為構造函數、std::make_shared<T>輔助函數和reset方法

1.1構造函數

就像普通的類一樣,需要在定義變量的時候,使用new 對象作為輸入參數。但是這種方法需要兩次申請內存空間,第一次是new,第二是智能對象本身需要申請的內存。

 

1.2std::make_shared<T>輔助函數

因為是在<memory>下的一個模板函數,實現了同時申請內存,推薦使用。例如

auto p = std::make_shared<Person>("Chris");

表示創建了智能指針對象,對Person對象進行管理,該Person對象的構造函數的輸入參數為字符串"Chris"。此時,可以使用auto自動推導。

 

1.3reset

就是讓智能指針對象重新指向一個新的對象,而對原來所指對象的計數減1。

在進行reset(new xxx())重新賦值時,智能指針對象首先是生成新的對象,然后將指針對象的引用計數減1(當然,若方法計數為0,則析構),然后將新對象的指針交給智能指針保管。

例如:

std::shared_ptr<Person> p1(new Person(1));// Person(1)的引用計數為1
p1.reset(new Person(3)); // 此時,p1先進行new Person(3),
// 然后p1會對Persion(1)的引用計數減1。此處為0,就會析構Person(1)。最后管理新的對象Person(3)

2.獲取原始指針

std::shared_ptr<int> p(new int(5));

int *pInt = p.get()

3.指定刪除器

默認刪除器不支持數組對象,所以需要指定刪除器。

4.注意事項

  • 原始指針只能初始化一個shared_ptr;
  • 在函數實參中不創建shared_ptr;
  • 禁止通過shared_from_this()返回this,這樣做可能造成二次析構;
  • 避免循環引用(智能指針最大的一個陷阱是循環引用)

  解決方法是使用weak_ptr;就是在相互調用的類中使用std::weak_ptr<A> wpa和std::weak_ptr<B> wpb,而不使用std::shared_ptr<A>和std::shared<B>,示例代碼如下:

struct AStruct;
struct BStruct;

struct AStruct
{
    std::weak_ptr<BStruct> bPtr;
    ~AStruct() { std::cout << "AStruct is deleted!" << std::endl; }
};

struct BStruct
{
    std::weak_ptr<AStruct> aPtr;
    ~BStruct() { std::cout << "BStruct is deleted!" << std::endl; }
};



void testLoopReference()
{
    std::shared_ptr<AStruct> spA(new AStruct);
    std::shared_ptr<BStruct> spB(new BStruct);

    spA->bPtr = spB;
    spB->aPtr = spA;
}

這樣就可以正常析構了

 

參考:

智能指針shared_ptr的用法

std::shared_ptr<T>::reset

https://en.cppreference.com/w/cpp/memory/shared_ptr

http://www.cplusplus.com/reference/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM