C語言?智能指針?shared_ptr?和?weak_ptr
weak_ptr引入可以解決shared_ptr交叉引用時無法釋放資源的問題。
示例代碼:
#include <iostream> #include <memory> using namespace std; class B; class A{ public: ? ? A(){cout << "A constructor ... "<< endl;} ? ? ~A(){cout << "A destructor ..." << endl;} ? ? std::shared_ptr<B> pb; }; class B{ public: ? ? B(){cout << "B constructor ... "<< endl;} ? ? ~B(){cout << "B destructor ..." << endl;} ? ? std::shared_ptr<A> pa; }; int main(int argc, char **argv) { ? ?? ? ? std::shared_ptr<int> a = std::make_shared<int>(3); ? ? std::shared_ptr<char> b = std::make_shared<char>('a'); ? ?? ? ? std::cout << "shared_ptr object(int) size = " << sizeof(a) << std::endl; ? ? std::cout << "shared_ptr object(char) size = " << sizeof(b) << std::endl; ? ?? ? ? std::weak_ptr<A> shadow_a; ? ? std::weak_ptr<B> shadow_b; ? ?? ? ? { ? ? std::shared_ptr<A> ptr_a = std::make_shared<A>(); ? ? std::shared_ptr<B> ptr_b = std::make_shared<B>(); ? ?? ? ? shadow_a = ptr_a; ? ? shadow_b = ptr_b; ? ?? ? ? ptr_a->pb = ptr_b; ? ? ptr_b->pa = ptr_a; ? ?? ? ? cout << "reference count of A = " << shadow_a.use_count() << endl; ? ? cout << "reference count of B = " << shadow_b.use_count() << endl; ? ? cout << endl;? ? ? } ? ?? ? ? cout << "reference count of A = " << shadow_a.use_count() << endl; ? ? cout << "reference count of B = " << shadow_b.use_count() << endl; ? ?? ? ? std::cout << "Hello, world!" << std::endl; ? ? return 0; }
運行代碼得到以下輸出:
shared_ptr object(int) size = 16
shared_ptr object(char) size = 16
A constructor ...
B constructor ...
reference count of A = 2
reference count of B = 2reference count of A = 1
reference count of B = 1
Hello, world!
從結(jié)果可以看出,由于交叉引用導(dǎo)致申請的內(nèi)存A,B無法正常釋放。
為什么會這樣呢?這個應(yīng)該從析構(gòu)原理進行考慮,shared_ptr引用計數(shù)需要為0才會進行析構(gòu)!但是ptr_a離開作用域會導(dǎo)致A引用計數(shù)減少1,但是A的引用計數(shù)此時為1,那么 pb不會釋放;同理,ptr_b離開作用域會導(dǎo)致B引用計數(shù)減少1,但是B的引用計數(shù)為此時為1,那么pa不會釋放。如此導(dǎo)致了資源無法釋放掉。
由于weak_ptr并不會改變shared_ptr的引用計數(shù),所以修改類A,和類B中的shared_ptr對象為weak_ptr對象即可釋放資源。
修改后的代碼如下:
#include <iostream> #include <memory> using namespace std; class B; class A{ public: ? ? A(){cout << "A constructor ... "<< endl;} ? ? ~A(){cout << "A destructor ..." << endl;} ? ? //std::shared_ptr<B> pb; ? ? std::weak_ptr<B> pb; }; class B{ public: ? ? B(){cout << "B constructor ... "<< endl;} ? ? ~B(){cout << "B destructor ..." << endl;} ? ? //std::shared_ptr<A> pa; ? ? std::weak_ptr<A> pa; }; int main(int argc, char **argv) { ? ?? ? ? std::shared_ptr<int> a = std::make_shared<int>(3); ? ? std::shared_ptr<char> b = std::make_shared<char>('a'); ? ?? ? ? std::cout << "shared_ptr object(int) size = " << sizeof(a) << std::endl; ? ? std::cout << "shared_ptr object(char) size = " << sizeof(b) << std::endl; ? ?? ? ? std::weak_ptr<A> shadow_a; ? ? std::weak_ptr<B> shadow_b; ? ?? ? ? { ? ? std::shared_ptr<A> ptr_a = std::make_shared<A>(); ? ? std::shared_ptr<B> ptr_b = std::make_shared<B>(); ? ?? ? ? shadow_a = ptr_a; ? ? shadow_b = ptr_b; ? ?? ? ? ptr_a->pb = ptr_b; ? ? ptr_b->pa = ptr_a; ? ?? ? ? cout << "reference count of A = " << shadow_a.use_count() << endl; ? ? cout << "reference count of B = " << shadow_b.use_count() << endl; ? ? cout << endl;? ? ? } ? ?? ? ? cout << "reference count of A = " << shadow_a.use_count() << endl; ? ? cout << "reference count of B = " << shadow_b.use_count() << endl; ? ?? ? ? std::cout << "Hello, world!" << std::endl; ? ? return 0; }
運行結(jié)果如下,可以正常釋放資源。
shared_ptr object(int) size = 16
shared_ptr object(char) size = 16
A constructor ...
B constructor ...
reference count of A = 1
reference count of B = 1B destructor ...
A destructor ...
reference count of A = 0
reference count of B = 0
Hello, world!
到此這篇關(guān)于C語言 智能指針 shared_ptr 和 weak_ptr的文章就介紹到這了,更多相關(guān) shared_ptr 和 weak_ptr內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ Log日志類輕量級支持格式化輸出變量實現(xiàn)代碼
這篇文章主要介紹了C++ Log日志類輕量級支持格式化輸出變量實現(xiàn)代碼,需要的朋友可以參考下2019-04-04C++中STL的優(yōu)先隊列priority_queue詳解
這篇文章主要介紹了C++中STL的優(yōu)先隊列priority_queue詳解,今天講一講優(yōu)先隊列(priority_queue),實際上,它的本質(zhì)就是一個heap,我從STL中扒出了它的實現(xiàn)代碼,需要的朋友可以參考下2023-08-08在c和c++中實現(xiàn)函數(shù)回調(diào)
如何在c和c++中實現(xiàn)函數(shù)回調(diào)呢?現(xiàn)在小編就和大家分享一下在c/c++中實現(xiàn)函數(shù)回調(diào)的示例代碼,需要的朋友可以參考下2013-07-07C++ leetcode之刪除并獲得點數(shù)的示例代碼
這篇文章主要介紹了C++ leetcode之刪除并獲得點數(shù)的示例代碼,本文給大家分享問題解析及解決方案,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05C++超詳細(xì)梳理lambda和function的使用方法
C++在C11標(biāo)準(zhǔn)中引入了匿名函數(shù),即沒有名字的臨時函數(shù),又稱之為lambda表達式.lambda表達式 實質(zhì)上是創(chuàng)建一個匿名函數(shù)/對象,這篇文章主要介紹了lambda和function的使用方法2022-08-08