智能指針 --- 循環引用問題、解決辦法

上一篇介紹了四種智能指針,四種智能指針的特點及使用方法

看段代碼:

class B;

class A
{
public:
    A(){ cout << "A()" << endl; }
    A(int i):a(i){ cout << "A(int)" << endl;}
    ~A(){ cout << "~A()" << endl;}

    shared_ptr<B> _bptr;
    int a;
};

class B
{
public:
    B(){ cout << "A()" << endl; }
    B(int i):b(i){ cout << "A(int)" << endl;}
    ~B(){cout << "~B()" << endl;}

    shared_ptr<A> _aptr;
    int b;
};

int main()
{
    shared_ptr<A> aptr(new A(10));
    shared_ptr<B> bptr(new B(10));
    cout << aptr.use_count() << endl;
    aptr -> _bptr = bptr;
    bptr -> _aptr = aptr;
    cout << aptr.use_count() << endl;
    return 0;
}

導致程序結束也沒有調用類的析構函數,在堆上申請的資源沒有得到正確的釋放,shared_ptr不恰當的使用帶來的循環用問題

這樣在函數返回的時候,shared_ptr<a> aptr  這個智能指針調用析構函數,對堆上的資源A的引用計數減一,此時引用計數爲1,不爲0,不調用delete函數,資源B同資源A一樣,引用計數爲1,這樣導致堆上的資源得不到正確的釋放,內存泄露。

改進方法:因爲在類的內部使用了帶有引用計數的強智能指針,導致對象的一直被循環引用,A對象內部的強智能指針指向B對象,B對象內部的強智能指針指向A對象。 把智能指針變成不使用引用計數的weak_ptr智能指針問題就得到解決了.(weak_ptr不增加引用計數,能看到引用計數)

class B;

class A
{
public:
    A(){ cout << "A()" << endl; }
    A(int i):a(i){ cout << "A(int)" << endl;}
    ~A(){ cout << "~A()" << endl;}

    weak_ptr<B> _bptr;      //修改成弱智能指針
    int a;
};

class B
{
public:
    B(){ cout << "A()" << endl; }
    B(int i):b(i){ cout << "A(int)" << endl;}
    ~B(){cout << "~B()" << endl;}

    weak_ptr<A> _aptr;     //修改成弱智能指針
    int b;
};

int main()
{
    shared_ptr<A> aptr(new A(10));
    shared_ptr<B> bptr(new B(10));
    cout << aptr.use_count() << endl;
    aptr -> _bptr = bptr;
    bptr -> _aptr = aptr;
    cout << aptr.use_count() << endl;
    return 0;
}

圖畫的有點醜,紅色和淡藍色的線是可以看到引用計數,但是不會增加引用計數

堅持✊

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