日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

shared_ptr 循环引用问题以及解决办法

發(fā)布時間:2024/10/14 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 shared_ptr 循环引用问题以及解决办法 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

栗子

#include <iostream> #include <memory>class CB; class CA { public:CA() { std::cout << "CA() called! " << std::endl; }~CA() { std::cout << "~CA() called! " << std::endl; }void set_ptr(std::shared_ptr<CB> &ptr) { m_ptr_b = ptr; }void b_use_count() { std::cout << "b use count : " << m_ptr_b.use_count() << std::endl; }void show() { std::cout << "this is class CA!" << std::endl; } private:std::shared_ptr<CB> m_ptr_b; };class CB { public:CB() { std::cout << "CB() called! " << std::endl; }~CB() { std::cout << "~CB() called! " << std::endl; }void set_ptr(std::shared_ptr<CA> &ptr) { m_ptr_a = ptr; }void a_use_count() { std::cout << "a use count : " << m_ptr_a.use_count() << std::endl; }void show() { std::cout << "this is class CB!" << std::endl; } private:std::shared_ptr<CA> m_ptr_a; };void test_refer_to_each_other() {std::shared_ptr<CA> ptr_a(new CA());std::shared_ptr<CB> ptr_b(new CB());std::cout << "a use count : " << ptr_a.use_count() << std::endl;std::cout << "b use count : " << ptr_b.use_count() << std::endl;ptr_a->set_ptr(ptr_b);ptr_b->set_ptr(ptr_a);std::cout << "a use count : " << ptr_a.use_count() << std::endl;std::cout << "b use count : " << ptr_b.use_count() << std::endl; }int main() {test_refer_to_each_other();return 0; }

結果

CA() called! CB() called! a use count : 1 b use count : 1 a use count : 2 b use count : 2

說明

上述結果說明,該?test_refer_to_each_other 執(zhí)行完成之后,并沒有釋放掉 CA 和 CB 兩個對象。因為起初定義完? ptr_a? 和 ptr_b 時,只有 ① ③ 兩條引用,然后調用函數(shù) set_ptr 后又增加了 ② ④ 兩條引用,當 test_refer_to_each_other 這個函數(shù)返回時,對象 ptr_a 和 ptr_b 被銷毀,也就是 ① ③ 兩條引用會被斷開,但是 ② ④ 兩條引用依然存在,每一個的引用計數(shù)都不為 0,結果就導致其指向的內(nèi)部對象無法析構,造成內(nèi)存泄漏。

解決辦法

解決這種狀況的辦法就是將兩個類中的一個成員變量改為?weak_ptr?對象。因為 weak_ptr 不會增加引用計數(shù),使得引用形不成環(huán),最后就可以正常的釋放內(nèi)部的對象,不會造成內(nèi)存泄漏,比如將?CB?中的成員變量改為?weak_ptr?對象,代碼如下:

class CB { public:CB() { cout << "CB() called! " << endl; }~CB() { cout << "~CB() called! " << endl; }void set_ptr(shared_ptr<CA>& ptr) { m_ptr_a = ptr; }void a_use_count() { cout << "a use count : " << m_ptr_a.use_count() << endl; }void show() { cout << "this is class CB!" << endl; } private:weak_ptr<CA> m_ptr_a; };

結果

CA() called! CB() called! a use count : 1 b use count : 1 a use count : 1 b use count : 2 ~CA() called! ~CB() called!

通過這次結果可以看到,CA 和 CB 的對象都被正常的析構了,引用關系如下圖所示,流程與上一例子相似,但是不同的是 ④ 這條引用是通過 weak_ptr 建立的,并不會增加引用計數(shù),也就是說 CA 的對象只有一個引用計數(shù),而 CB 的對象只有 2 個引用計數(shù),當 test_refer_to_each_other 這個函數(shù)返回時,對象 ptr_a 和 ptr_b 被銷毀,也就是①③兩條引用會被斷開,此時CA對象的引用計數(shù)會減為0,對象被銷毀,其內(nèi)部的 m_ptr_b 成員變量也會被析構,導致 CB 對象的引用計數(shù)會減為0,對象被銷毀,進而解決了引用成環(huán)的問題。

?

(SAW:Game Over!)

總結

以上是生活随笔為你收集整理的shared_ptr 循环引用问题以及解决办法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。