網(wǎng)站首頁(yè) 編程語(yǔ)言 正文
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!
原文鏈接:https://blog.csdn.net/lybhit/article/details/122799780
相關(guān)推薦
- 2022-10-03 React如何實(shí)現(xiàn)全屏監(jiān)聽(tīng)Esc鍵_React
- 2022-07-06 詳解C語(yǔ)言中sizeof如何在自定義函數(shù)中正常工作_C 語(yǔ)言
- 2022-11-06 Android?Navigation重建Fragment問(wèn)題分析及解決_Android
- 2022-12-04 Python中的配對(duì)函數(shù)zip()解讀_python
- 2022-11-07 python單元測(cè)試框架unittest基本用法案例_python
- 2022-08-15 使用volatile保證多線程之間實(shí)例變量的可見(jiàn)性
- 2022-06-16 如何使用shell獲取進(jìn)程名的內(nèi)存以及CPU利用率_linux shell
- 2022-05-08 總結(jié)Python函數(shù)參數(shù)的六種類(lèi)型_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過(guò)濾器
- Spring Security概述快速入門(mén)
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支