智能指針的交叉引用

關於智能指針的交叉引用以及解決方法~~

智能指針的交叉引用會導致什麼問題呢??首先,先來看以下一段代碼……

class B;
class A
{
public:
    shared_ptr<B> _pb;
};
class B
{
public:
    shared_ptr<A> _pa;
};
int main()
{
    shared_ptr<A> pa(new A);
    shared_ptr<B> pb(new B);
    pa->_pb = pb;
    pb->_pa = pa;
    return 0;
}

顯而易見,類A中有一個指向類B的shared_ ptr強類型智能指針,類B中有一個指向類A的shared_ ptr強類型智能指針

此時,有兩個強智能指針指向了對象A,對象A的引用計數爲2。也有兩個強智能指針指向了對象B,對象B的引用計數爲2。對象A與對象B的關係如圖所示
這裏寫圖片描述
當主函數return返回後,對象A的引用計數減一變爲1,對象B的引用計數減一變爲1,此時因爲引用計數不爲0,所以不能析構對象釋放內存,程序結束造成內存泄漏

解決方法:將類A和類B中的shared_ptr強智能指針都換成weak_ptr弱智能指針

class B;
class A
{
public:
    weak_ptr<B> _pb;
};
class B
{
public:
    weak_ptr<A> _pa;
};
int main()
{
    shared_ptr<A> pa(new A);
    shared_ptr<B> pb(new B);
    pa->_pb = pb;
    pb->_pa = pa;
    return 0;
}

weak_ptr弱智能指針,雖然有引用計數,但實際上它並不增加計數,而是隻觀察對象的引用計數,weak_ptr的引用計數指的是有多少個weak_ptr在觀察同一個shared_ptr。而shared_ptr強智能指針的引用計數是對資源的引用計數所以此時對象A的引用計數只爲1,對象B的引用計數也只爲1。此時對象A與對象B的關係如圖所示
這裏寫圖片描述
當主函數return返回後,對象A的引用計數減一變爲0,所以正常析構對象A;對象B的引用計數減一變爲0,所以正常析構對象B,此時不會造成內存泄漏

總結:創建對象的時候用shared_ptr強智能指針,別的地方一律持有weak_ptr弱智能指針。

哈哈,是不是又發現你的程序中有一個bug,卻不知道哪裏的問題,那就趕緊檢查檢查是不是智能指針惹的禍→_→*

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章