weak_ptr解除循環參考

來源:互聯網
上載者:User

先看一下shared_ptr的正確用法:

class A {public:    A() {        cout << "A::A()" << endl;    }        ~A() {        cout << "A::~A()" << endl;    }        shared_ptr<B> b;};class B {public:    B() {        cout << "B::B()" << endl;    }        ~B() {        cout << "B::~B()" << endl;    }    public:    shared_ptr<A> a;};/* *  */int main(int argc, char** argv) {        shared_ptr<A> x(new A);

此時運行程式,顯示:

A::A()A::~A()

好,A對象被正確的建立和銷毀了。

但是注意A對象裡面有一個shared_ptr指向B.

現在修改一下代碼,讓它出現循環參考。

int main(int argc, char** argv) {        shared_ptr<A> x(new A);    x->b = shared_ptr<B>(new B);    x->b->a = x;    return 0;}

再運行程式,觀察結果:

A::A()B::B()

A和B對象都未釋放。為什嗎?

因為第一行x指向的A對象,A對象的引用計數為1,

第二行 x->b指向B對象,B對象的引用計數為1

第三行B對象裡面的a也指向了A對象,因此A對象的引用計數為2

當退出main函數的時候,

1.x的解構函式會將A對象的引用計數從2減到1,但是因為不是0,所以A對象的解構函式不會被調用。

2.因此A裡面成員變數b的解構函式就不會被調用。

3.所以B的引用計數也是1. 

4.所以出現了兩個記憶體流失,A和B對象都沒有被銷毀。

為了打破這個循環參考,試試weak_ptr。只需要修改一行代碼即可,將B的成員a改成wear_ptr<A>類型。下面是完整代碼:

class B;class A {public:    A() {        cout << "A::A()" << endl;    }        ~A() {        cout << "A::~A()" << endl;    }        shared_ptr<B> b;};class B {public:    B() {        cout << "B::B()" << endl;    }        ~B() {        cout << "B::~B()" << endl;    }    public:    weak_ptr<A> a;};/* *  */int main(int argc, char** argv) {        shared_ptr<A> x(new A);    x->b = shared_ptr<B>(new B);    x->b->a = x;    return 0;}

運行結果:

A::A()B::B()A::~A()B::~B()

問題解決。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.