当前位置: 首页 > news >正文

shared_ptr简单应用

shared_ptr 是C++共享指针,往往应用在动态分配内存的场景下。相较于new操作符的优势在于shared_ptr共享指针可以自动进行动态内存释放,而new必须与delete配合使用,否则会造成内存泄露。

一个好的建议是:坚持只使用智能指针,就可以避免忘记delete造成的内存泄露,避免同一块内存被释放两次的问题。对于一块内存,只有在没有任何智能指针指向它的情况下才会自动释放它。

shared_ptr还可以作为class的成员,以使该class的对象能够共享数据。下面的代码进行了一下简单的实践。

#include<iostream>#include<memory>#include<initializer_list>#include<vector>usingnamespacestd;classintBlob{friendostream&printBlob(ostream&os,intBlob&blob);public:explicitintBlob(initializer_list<int>il):data_(make_shared<vector<int>>(il)){std::cout<<"列表初始化构造函数"<<std::endl;}intBlob():data_(make_shared<vector<int>>()){std::cout<<"默认构造函数"<<std::endl;}intBlob(constintBlob&blob):data_(blob.data_){std::cout<<"拷贝构造函数"<<std::endl;}intBlob&operator=(constintBlob&b2){data_=b2.data_;return*this;}~intBlob(){std::cout<<"析构函数"<<std::endl;}voidpush_back(intd);voidprintUseCount(){std::cout<<"shared_ptr used count: "<<data_.use_count()<<endl;}private:shared_ptr<vector<int>>data_;};voidintBlob::push_back(intd){data_->push_back(d);}ostream&printBlob(ostream&os,intBlob&blob){os<<"blob data size:"<<blob.data_->size()<<std::endl;for(auto&d:*(blob.data_)){os<<d<<" ";}os<<std::endl;}intmain(){intBlob B1{0,1,2,3,4,5,6,7,8,9};{intBlobB2(B1);printBlob(cout,B1);//这里说明友元函数可以访问class的私有成员printBlob(cout,B2);B1.printUseCount();B2.printUseCount();B2.push_back(10);}//出该作用域前B2对象会被析构,shared_ptr内部的计数器自动减1,因此会看到下面的B1.printUseCount()变成了1B1.printUseCount();printBlob(cout,B1);//B2对data所指的vector进行了push_back,虽然这里B2已经被析构了,但是B1所用的vector也有了10//可以看出B1和B2确实共享了数据intBlob B3;printBlob(cout,B3);return0;}

运行结果

列表初始化构造函数 拷贝构造函数 blob data size:10 0 1 2 3 4 5 6 7 8 9 blob data size:10 0 1 2 3 4 5 6 7 8 9 shared_ptr used count: 2 shared_ptr used count: 2 析构函数 shared_ptr used count: 1 blob data size:11 0 1 2 3 4 5 6 7 8 9 10 默认构造函数 blob data size:0 析构函数 析构函数

shared_ptr可以使用普通的内置指针进行初始化,但是这样做是有风险的。如下:

int*p=newint(50);shared_ptr<int>p1_shared(p);shared_ptr<int>p2_shared(p);shared_ptr<int>p3_shared(p1_shared);std::cout<<p1_shared.use_count()<<" "<<p2_shared.use_count()<<" "<<p3_shared.use_count()<<std::endl;

打印结果如下:

2 1 2

实际上p1_shared、p2_shared和p3_shared都指向同一个int对象,所以use_count都为3才是正确的。但是如果用一个内置指针单独去初始化不同的shared_ptr,则智能指针内部的计数器是感受不到的。因此在释放内存的时候就可能产生悬空指针。p3_shared因为是用p1_shared初始化的,所以它和p1_shared的use_count打印为2,也就是它们都不知道还有一个p2_shared也指向了同一个内存。

因此不要混用普通指针和智能指针。

http://www.jsqmd.com/news/1282048/

相关文章:

  • 3步安装!GBFR-Logs:碧蓝幻想Relink玩家的终极战斗数据分析工具
  • 行业观察:2026 长沙本土财税机构实力对比,靠谱代理记账服务商参考名录出炉 - 财税推荐官
  • 2026杭州办公室装修设计工装公司哪家靠谱?全业态深度解析指南 - 装修新知
  • 27.4%高增速!工业6G网关2026-2032年增长预期释放产业新动能
  • 还在为无法保存微信视频号内容而烦恼吗?这个神器让你轻松捕获全网视频资源
  • 京城芬迪Peekaboo与法棍包回收价值PK:同门双雄,谁在二手市场更受欢迎? - 日常财经早知道
  • log4j:WARN No appenders could be found for logger 报错解决办法
  • 电商项目专题(三)-项目搭建
  • P1332 血色先锋队复盘
  • 2026新版遂宁防水补漏服务商参考|阳台渗漏修缮方案指南 - 筑宅安
  • 2026年武汉黄陂区管道疏通避坑指南:金池师傅教你识别隐形收费 - 余生黄金回收
  • 2026西安黄金回收五区深度走访实录:未央雁塔长安灞桥莲湖,把临街门店的真实内幕一次说清 - 人间烟火小记
  • 基于SpringBoot的企业人事管理系统(Java+SpringBoot+MySQL)| 计算机毕业设计 附源码论文PPT
  • CT值到灰度值的映射, 以及windowing中的窗宽和窗位
  • 3步掌握星露谷物语农场规划器:免费工具打造完美农场
  • 免费开源鼠标连点器终极指南:5分钟快速实现自动化点击
  • 2026松江管道疏通防坑实测邻里帮师傅上门快 - 余生黄金回收
  • P1135 奇怪的电梯复盘
  • Blender终极贝塞尔曲线插件:Flexi工具完全指南
  • Kubernetes 的 Annotation
  • 如何用yuzu模拟器在电脑上打造专属Switch游戏体验?
  • 剔除套路商家,2026石家庄黄金回收优选排名,石家庄卖黄金直接参考 - 资讯洞察员
  • 如何实现终极Android Root隐藏:SUSFS4KSU模块完整指南
  • 2026年句容黄金回收实战指南:成色检测与计量避坑全攻略 - 微城市网络
  • Palworld存档工具终极指南:3种方法实现高效数据解析与转换
  • 一部60分钟AI长片拿下了广电许可证:当开源冲破2.8万亿参数,AI影视化的最后一道坎在哪?
  • 2026年全自行升降机、全自行升降平台厂家推荐 - 优企甄选
  • 如何彻底告别Windows磁盘空间不足:WinDirStat完全指南
  • C语言—求第n个斐波那契数列的值(非递归)
  • 【单片机毕业设计推荐】基于 STM32 的智能温室环境监测与自动调控系统设计,基于 STM32 的盆栽智能水肥光照综合管理装置设计(011704)