天天看點

c++語言基礎-----<智能指針>

文章目錄

    • 對智能指針的思考
      • shared_ptr
      • enable_shared_from_this
      • weak_ptr
      • Unique_ptr

對智能指針的思考

shared_ptr

設計意圖是為了更友善,更安全的管理堆上配置設定的對象。

原理是利用了

raii

的特性在對象出作用域後會自動調用析構函數,進而在判定自己是最後一個持有管理對象的情況下,調用其析構函數,釋放記憶體。

特性 { 構造,copy構造,指派,移動構造,移動指派}

  • std::shared_ptr<int> a(new int(1));       //a:use 1
    std::shared_ptr<int> b(a);                //b:use 2 ; a:use 2     
    std::shared_ptr<int> c(std::move(b));     //c:use 2 ; a:use 2 ; b:empty
               

enable_shared_from_this

C11新特性

weak_ptr

設計意圖: 這裡我想從它的特性來反看為啥設計這個東西。

它的特性是: 不參與控制所指對象的生命周期, 在

shared_ptr

發現自己是最後一個管理對象的時候,在其析構的時候會直接釋放掉所管理的對象,即使這個時候還有

weak_ptr

指向這個對象,是以在用它的時候要先

lock()

一下看看傳回的是不是空的

shared_ptr

它與直接用裸指針的差別是 它可以檢測所指的對象是否被析構

是以這裡可以看出來

weak_ptr

是為了配合

shared_ptr

來控制所接管對象的,并且從它的源碼可以看出它不能直接接管所指對象,如下。

weak_ptr<classType> type(new ClassType) //這樣不行

疑問 :如下

nn1 == nn3 == 8

編譯器配置設定了8個位元組 其中4個位元組的指針來指向接管的對象,另外4位元組指針指向一個控制塊,我的問題是這個控制塊裡為啥要分 強引用計數 和 弱引用計數 ,弱引用計數有啥用我感覺可以去掉!

//接上面的 win32 debug平台
std::weak_ptr<IBase> d(c);

int nn1 = sizeof(d);
int nn3 = sizeof(c);   
           

場景 循環引用打破

class IBaseA
{
    shared_ptr<IBaseB>  m_iB;
};

class IBaseB
{
    shared_ptr<IBaseA> m_iA;
}

{
    std::shared_ptr<IBaseA> IA(new IBaseA);
	std::shared_ptr<IBaseB> IB(new IBaseB)

	IA->m_iB = IB;
    
	IB->m_iA = IA;
    
    assert(IA.use_count() == 2);
    assert(IB.use_count() == 2);
}
//出作用域後 明明沒有shared_ptr指向 IBaseA 或 IBaseB, 但由于它們引用計數都是二是以即使出作用域也是改為1 造成記憶體洩漏。
           

參考連接配接 :SharedAnalyse

Unique_ptr

特性 與

shared_ptr

不同它沒有 copy構造函數與指派運算符。vs中源碼如下:

class unique_ptr
{	// non-copyable pointer to an object
public:
    //....
	unique_ptr(const unique_ptr&) = delete;
	unique_ptr& operator=(const unique_ptr&) = delete;
    
    unique_ptr(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept;
    
    unique_ptr& operator=(unique_ptr<_Ty2, _Dx2>&& _Right) noexcept
    {	// assign by moving _Right
        reset(_Right.release());
        this->get_deleter() = _STD forward<_Dx2>(_Right.get_deleter());
        return (*this);
    }
};
           

同一時刻隻能有一個

unique_ptr

接管所指的對象, 它與

auto_ptr

不同之處在與它可以放在容器中,這就是利用了它雖然不能copy但能移動構造的特點。

設計意圖 這方面我覺得它是為了用更小的代價來管理所接管對象,因為比之

shared_ptr

來說它不用維護一個引用計數器。

繼續閱讀