shared_ptr的概念和一些特性調查

227569hy發表於2024-05-17

shared_ptr

概念

shared_ptr 是 C++11 中引入的一種智慧指標,用於自動管理資源,特別是動態分配的記憶體。它屬於 標頭檔案中定義的智慧指標類之一,用於解決動態記憶體分配中的記憶體洩漏和資源生命週期管理問題。shared_ptr 透過引用計數機制來實現多個 shared_ptr 例項共享同一資源。

具有較好的安全性,可以避免記憶體洩漏和懸掛指標問題。

特性

執行緒安全的說明

shared_ptr 自身的引用計數是執行緒安全的,但指向的物件本身不是執行緒安全的。如果多個執行緒需要訪問同一物件,需要額外的同步機制。

二進位制相容性

如果客戶程式碼裡有 new Bar,那麼肯定不安全,因為 new 的位元組數不夠裝下新 Bar。相反,如果 library 透過 factory 返回 Bar* (並透過 factory 來銷燬物件)或者直接返回 shared_ptr,客戶端不需要用到 sizeof(Bar),那麼可能是安全的。
即把建立交給動態庫,而不是由客戶自己建立。

陳碩部落格

shared_ptr的解構函式可以呼叫基類的沒有設定為virtual的解構函式

#include <iostream>
#include <memory>

class base
{
public:
    base()
    {
        std::cout << "base constructor" << std::endl;
    }
    ~base()
    {
        std::cout << "base destructor" << std::endl;
    }
};

class test: public base
{
public:
    test(): base()
    {
        std::cout << "test constructor" << std::endl;
    }
    ~test()
    {
        std::cout << "test destructor" << std::endl;
    }
};


int main()
{
    std::cout << "test shared_ptr------------" << std::endl;
    {
        std::shared_ptr<base> ptr(new test);
    }

    std::cout << "test unique_ptr------------" << std::endl;
    {
        std::unique_ptr<base> ptr(new test);
    }
    return 0; // success
}

輸出結果是:

test shared_ptr------------
base constructor
test constructor
test destructor
base destructor
test unique_ptr------------
base constructor
test constructor
base destructor

可以發現shared_ptr可以在析構時自動釋放資源沒有設定基類為虛解構函式的基類,而unique_ptr不行。

查閱原始碼調查原因發現:
shared_ptr中,會判斷是否存在基類
並且建立一個指向基類的指標:
mutable __weak_ptr<_Tp, _Lp> _M_weak_this;
image

當析構的時候會一併呼叫_M_weak_this的解構函式,也就是基類的解構函式.

shared_ptr能實現這一點主要在於:
shard_ptr構造的時候,會去判斷指標的型別,並結合shared_ptr的模板引數
image

unique_ptr之所以實現不了這種特性,是因為unique_ptr預設採用的是default_delete,而default_delete的模板引數是由unique_ptr的模板引數決定的。所以導致其不能實現。
image

但unique_ptr的優點就是可以靈活的更換delete函式。

相關文章