news 2026/7/28 17:54:40

shared_ptr简单应用

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
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也指向了同一个内存。

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

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/28 17:53:38

提示工程不是终点,而是起点:资深架构师拆解AI时代6层能力金字塔

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;提示工程的本质与边界认知 提示工程不是魔法咒语的堆砌&#xff0c;而是人与语言模型之间建立可解释、可复现、可验证的认知契约。其本质在于将人类意图精准编码为模型可理解的结构化指令&#xff0c;同时清醒…

作者头像 李华
网站建设 2026/7/28 17:53:04

HDU 6725 Diversity (简单树形DP) 2019百度之星复赛

Diversity Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 27 Accepted Submission(s): 19 Problem Description 给你一棵n个点的树&#xff0c;对于节点i&#xff0c;你要给它标上一个[li,ri]之间的数&a…

作者头像 李华
网站建设 2026/7/28 17:52:48

27.4%高增速!工业6G网关2026-2032年增长预期释放产业新动能

一、核心定义&#xff1a;面向6G演进的工业现场智能连接入口首先要厘清行业最容易踩的认知误区&#xff1a;当前市场不存在大规模量产的纯6G商用网关&#xff0c;我们统计的是‌6G-ready工业蜂窝网关‌赛道——这类产品面向工业现场未来无线化、智能化和确定性连接需求&#xf…

作者头像 李华
网站建设 2026/7/28 17:51:22

跨境电商BI最佳实践FAQ:从多平台数据到经营决策的落地问答

导语 做跨境电商的卖家&#xff0c;日常运营几乎都会遇到这三个扎心问题&#xff1a; 第一&#xff0c;亚马逊、速卖通、Shopee、独立站等多平台店铺数据分散在不同后台&#xff0c;每次做周度经营复盘&#xff0c;运营和数据人员都要花1-2天从各个平台导出数据&#xff0c;再手…

作者头像 李华
网站建设 2026/7/28 17:49:52

复习卷积运算

复习卷积运算https://www.cnblogs.com/shine-lee/p/9932226.html

作者头像 李华
网站建设 2026/7/28 17:49:30

调试错误解决方案之VC++

文|Seraph这篇文章主要用来记录使用Visual Studio过程中&#xff0c;出现的各种error&#xff0c;并提供自己当时解决的方案。 但是&#xff0c;一个error可能由不用原因引起的&#xff0c;文中案例仅供大家参考。nafxcwd.lib(thrdcore.obj) : error LNK2001: unresolved exter…

作者头像 李华