C語(yǔ)言?智能指針?shared_ptr?和?weak_ptr
weak_ptr引入可以解決shared_ptr交叉引用時(shí)無(wú)法釋放資源的問(wèn)題。
示例代碼:
#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;
}運(yùn)行代碼得到以下輸出:
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)致申請(qǐng)的內(nèi)存A,B無(wú)法正常釋放。
為什么會(huì)這樣呢?這個(gè)應(yīng)該從析構(gòu)原理進(jìn)行考慮,shared_ptr引用計(jì)數(shù)需要為0才會(huì)進(jìn)行析構(gòu)!但是ptr_a離開(kāi)作用域會(huì)導(dǎo)致A引用計(jì)數(shù)減少1,但是A的引用計(jì)數(shù)此時(shí)為1,那么 pb不會(huì)釋放;同理,ptr_b離開(kāi)作用域會(huì)導(dǎo)致B引用計(jì)數(shù)減少1,但是B的引用計(jì)數(shù)為此時(shí)為1,那么pa不會(huì)釋放。如此導(dǎo)致了資源無(wú)法釋放掉。
由于weak_ptr并不會(huì)改變shared_ptr的引用計(jì)數(shù),所以修改類(lèi)A,和類(lèi)B中的shared_ptr對(duì)象為weak_ptr對(duì)象即可釋放資源。
修改后的代碼如下:
#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;
}
運(yùn)行結(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語(yǔ)言 智能指針 shared_ptr 和 weak_ptr的文章就介紹到這了,更多相關(guān) shared_ptr 和 weak_ptr內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C++ Log日志類(lèi)輕量級(jí)支持格式化輸出變量實(shí)現(xiàn)代碼
這篇文章主要介紹了C++ Log日志類(lèi)輕量級(jí)支持格式化輸出變量實(shí)現(xiàn)代碼,需要的朋友可以參考下2019-04-04
C++中異常處理的基本思想及throw語(yǔ)句拋出異常的使用
這篇文章主要介紹了C++中異常處理的基本思想及throw類(lèi)拋出異常的使用,也深入談到了異常被拋出后的棧解旋unwinding過(guò)程,需要的朋友可以參考下2016-03-03
C++中STL的優(yōu)先隊(duì)列priority_queue詳解
這篇文章主要介紹了C++中STL的優(yōu)先隊(duì)列priority_queue詳解,今天講一講優(yōu)先隊(duì)列(priority_queue),實(shí)際上,它的本質(zhì)就是一個(gè)heap,我從STL中扒出了它的實(shí)現(xiàn)代碼,需要的朋友可以參考下2023-08-08
在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)
如何在c和c++中實(shí)現(xiàn)函數(shù)回調(diào)呢?現(xiàn)在小編就和大家分享一下在c/c++中實(shí)現(xiàn)函數(shù)回調(diào)的示例代碼,需要的朋友可以參考下2013-07-07
C++ leetcode之刪除并獲得點(diǎn)數(shù)的示例代碼
這篇文章主要介紹了C++ leetcode之刪除并獲得點(diǎn)數(shù)的示例代碼,本文給大家分享問(wèn)題解析及解決方案,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05
C++中類(lèi)型推斷(auto和decltype)的使用
在C++11之前,每個(gè)數(shù)據(jù)類(lèi)型都需要在編譯時(shí)顯示聲明,在運(yùn)行時(shí)限制表達(dá)式的值,但在C++的新版本之后,引入了 auto 和 decltype等關(guān)鍵字,本文就來(lái)介紹一下C++中類(lèi)型推斷(auto和decltype)的使用,感興趣的可以了解一下2023-12-12
C++超詳細(xì)梳理lambda和function的使用方法
C++在C11標(biāo)準(zhǔn)中引入了匿名函數(shù),即沒(méi)有名字的臨時(shí)函數(shù),又稱(chēng)之為lambda表達(dá)式.lambda表達(dá)式 實(shí)質(zhì)上是創(chuàng)建一個(gè)匿名函數(shù)/對(duì)象,這篇文章主要介紹了lambda和function的使用方法2022-08-08

