weak_ptr打破环状引用
轉(zhuǎn)自:http://blog.csdn.net/malong777/article/details/48974559
weak_ptr是一種不控制對象生存周期的智能指針,它指向一個shared_ptr管理的對象...它不會改變shared_ptr的引用計(jì)數(shù)——《C++ Primer .5th》。很明顯,weak_ptr的特點(diǎn)是“弱引用”。有什么用?應(yīng)用場景是什么地方?
??? 考慮它的胞兄shared_ptr,每次復(fù)制之后引用計(jì)數(shù)加一,不再指向?qū)ο?#xff08;自身銷毀或指向其他對象)時時引用計(jì)數(shù)減一,減至零值調(diào)用所管理資源對象的析構(gòu)函數(shù)。考慮這樣一個情況,兩個對象各自包含指向彼此的shared_ptr成員,形成環(huán)狀引用,引用計(jì)數(shù)永遠(yuǎn)為1,不能銷毀,造成內(nèi)存泄漏。
//x86_64 win7_64 vs2013 ultimate #include <iostream> #include <string> #include <memory> using namespace std; class A; class B; class A{ public: ~A(){ cout << "destroying A\n" ; } shared_ptr<B> pb; }; class B{ public: ~B(){ cout << "destroying B\n" ; } shared_ptr<A> pa; }; void test(){ shared_ptr<A> a(new A()); shared_ptr<B> b(new B()); a->pb = b; b->pa = a; } int main(){ cout << "begin test...\n"; test(); cout << "end test\n"; } output: begin test... end test 請按任意鍵繼續(xù). . .?在函數(shù)test()中便是剛才提到的情形,A、B的對象分別被彼此的shared_ptr所引用,離開test()作用域后,A、B對象再也不能被用戶訪問,因?yàn)橹悄苤羔榓、b被銷毀了,但是各自引用計(jì)數(shù)為1,兩個對象的內(nèi)存再也不會被釋放,可怕的內(nèi)存泄漏就此產(chǎn)生。
?
??? 那么weak_ptr對此又有幫助呢?考慮如果將B中的智能指針換成weak_ptr<A>,回過頭看test()里發(fā)生了什么?首先shared_ptr版本的a、b初始化,引用計(jì)數(shù)各自為1,然后將b賦值給A中的shared_ptr,B對象引用計(jì)數(shù)變?yōu)?,將a賦值給B中的weak_ptr,此操作不改變shared_ptr<A>的引用計(jì)數(shù),依舊為1。退出test作用域,a、b析構(gòu),B引用計(jì)數(shù)變?yōu)?,A的引用計(jì)數(shù)為0。A的析構(gòu)函數(shù)被調(diào)用,A中的shared_ptr<B>也被銷毀,即B的引用計(jì)數(shù)再次減1變?yōu)?,調(diào)用B的析構(gòu)函數(shù)。此時,內(nèi)存已經(jīng)被全部回收。
1 class B{ 2 public: 3 ~B(){ cout << "destroying B\n" << endl; } 4 weak_ptr<A> pa; 5 }; 6 output: 7 begin test... 8 destroying A 9 10 destroying B 11 12 end test 13 請按任意鍵繼續(xù).?實(shí)際用用的例子,想象在一個tree結(jié)構(gòu)中,父節(jié)點(diǎn)通過一個共享所有權(quán)的引用(chared_ptr)引用子節(jié)點(diǎn),同時子節(jié)點(diǎn)又必須持有父節(jié)點(diǎn)的引用。如果這第二個引用也共享所有權(quán),就會導(dǎo)致一個循環(huán),最終兩個節(jié)點(diǎn)內(nèi)存都無法釋放。
轉(zhuǎn)載于:https://www.cnblogs.com/13224ACMer/p/6404068.html
總結(jié)
以上是生活随笔為你收集整理的weak_ptr打破环状引用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于AM335X移植SDIO WIFI的
- 下一篇: P1080 国王游戏