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

【C++指针】 shared_ptr共享指针

shared_ptr 图解

一、什么是智能指针?

智能指针=自动管理内存的指针

// 传统指针的痛点int*p=newint(10);// ... 一堆代码deletep;// 万一忘了写?内存泄漏!// 智能指针的优雅#include<memory>shared_ptr<int>sp(newint(10));// 不用写 delete!自动释放!

二、shared_ptr 核心特性

特性说明
共享所有权多个指针可指向同一对象
引用计数记录有多少指针在共享
自动释放最后一个指针销毁时,自动删除对象

三、创建 shared_ptr 的三种方式

1. 直接 new(不推荐)

shared_ptr<int>sp1(newint(100));// 单个intshared_ptr<int[]>sp2(newint[10]);// int数组(C++17)

2. make_shared(✅ 推荐)

autosp3=make_shared<int>(100);// 单个int,值100autosp4=make_shared<string>("hello");// string对象autosp5=make_shared<vector<int>>();// vector容器

3. 拷贝构造

autosp6=sp3;// sp6 和 sp3 指向同一对象

四、引用计数:核心机制

autosp=make_shared<int>(10);cout<<sp.use_count();// 输出:1(只有sp自己)autosp2=sp;// 复制cout<<sp.use_count();// 输出:2(sp和sp2共享)cout<<sp2.use_count();// 输出:2{autosp3=sp;// 又复制一个cout<<sp.use_count();// 输出:3}// sp3 销毁,计数-1cout<<sp.use_count();// 输出:2sp2.reset();// sp2 放弃指向cout<<sp.use_count();// 输出:1sp.reset();// 最后一个也放弃// 此时计数为0,对象被自动删除

计数变化图解

开始:sp ──→ [数据:10] 计数=1 sp2复制:sp ──→ [数据:10] ←── sp2 计数=2 sp3复制:sp ──→ [数据:10] ←── sp2 计数=3 ↑ sp3 sp3销毁:sp ──→ [数据:10] ←── sp2 计数=2 sp2.reset:sp ──→ [数据:10] 计数=1 sp.reset:对象被删除

五、常用操作详解

1. 解引用和成员访问

autosp=make_shared<int>(10);*sp=20;// 修改值cout<<*sp;// 读取值autospStr=make_shared<string>("hello");cout<<spStr->size();// 调用成员函数(*spStr)[0]='H';// 修改字符

2. 获取原始指针

autosp=make_shared<int>(10);int*raw=sp.get();// 获取原始指针// ⚠️ 警告:raw只是查看,不能删除!// delete raw; // 千万不要!// shared_ptr<int> sp2(raw); // 千万不要!

3. 重置指针

autosp=make_shared<int>(10);sp.reset();// 放弃指向,计数-1// 也可以重置并指向新对象sp.reset(newint(20));// 指向新int,原对象计数-1

4. 检查是否为空

autosp=make_shared<int>(10);if(sp){// ✅ 简洁写法cout<<"指针不为空";}if(sp.get()!=nullptr){// ⚠️ 繁琐写法cout<<"指针不为空";}

六、自定义删除器

在需要特殊清理时使用:

// 方式1:普通函数voidDeleteInt(int*p){cout<<"自定义删除函数"<<endl;deletep;}shared_ptr<int>sp1(newint(10),DeleteInt);// 方式2:Lambda表达式(推荐)shared_ptr<int>sp2(newint(10),[](int*p){cout<<"Lambda删除"<<endl;deletep;});// 实际应用:管理文件句柄shared_ptr<FILE>spFile(fopen("test.txt","w"),[](FILE*f){fclose(f);cout<<"文件已关闭"<<endl;});

七、数组支持

// C++17 开始支持数组shared_ptr<int[]>spArr(newint[100]);// ✅spArr[0]=10;// 数组用 [] 访问// 推荐写法autospArr2=make_shared<int[]>(100);// C++20

八、指向成员的特殊用法

structPerson{string name;intage;doublescore;};autop=make_shared<Person>();// 指向对象的某个成员,但共享整个对象的生命周期shared_ptr<string>spName(p,&p->name);shared_ptr<int>spAge(p,&p->age);cout<<p.use_count();// 输出:3(三个指针共享整个Person)// 即使 spName、spAge 只指向成员,它们仍然控制整个对象的生命周期

九、常见错误(一定要记住!)

❌ 错误1:手动删除 get() 返回的指针

autosp=make_shared<int>(10);deletesp.get();// 灾难!会重复删除导致崩溃

❌ 错误2:用原始指针创建多个 shared_ptr

int*p=newint(10);shared_ptr<int>sp1(p);shared_ptr<int>sp2(p);// 灾难!两个独立管理同一内存// 程序结束时两次 delete,崩溃!

❌ 错误3:循环引用(高级话题)

structNode{shared_ptr<Node>next;};autoa=make_shared<Node>();autob=make_shared<Node>();a->next=b;b->next=a;// 互相引用,都无法释放!// 解决方案:用 weak_ptr

❌ 错误4:忘记数组语法

shared_ptr<int>sp(newint[10]);// 错误!会调用 delete 不是 delete[]shared_ptr<int[]>sp(newint[10]);// 正确!

十、最佳实践总结

✅ 推荐这样做

// 1. 优先用 make_sharedautosp=make_shared<int>(10);// 2. 用 auto 简化代码autospVec=make_shared<vector<int>>();// 3. 用 if(sp) 检查空指针if(sp){/* 使用 */}// 4. 需要特殊清理时用 LambdaautospFile=shared_ptr<FILE>(fopen("a.txt","r"),[](FILE*f){fclose(f);});

❌ 避免这样做

// 1. 滥用 get()int*raw=sp.get();// 除非必要// 2. 手动管理引用计数// 让系统自动处理就好// 3. 混用原始指针和智能指针

十一、一句话记忆

shared_ptr 就像合租室友:有人搬进来计数+1,有人搬走计数-1,最后一个离开时负责打扫房间(删除对象)。你只需要安心住,不用操心打扫的事!

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

相关文章:

  • 2026最新SATA连接器品牌TOP5评测!权威榜单发布 - 十大品牌榜
  • 2026年知名的组合清理去石机/山东组合清理去石机厂家热卖产品推荐(近期) - 品牌宣传支持者
  • 小白程序员必看!收藏这份视觉-语言模型(VLM)入门指南,轻松入门大模型
  • 2026年2月家用电梯公司推荐,轻量化设计不破坏房屋结构 - 品牌鉴赏师
  • 永辉购物卡处理,教你避开非正规渠道的深坑 - 团团收购物卡回收
  • 收藏必备!小白程序员必看:大模型如何赋能中医药创新与突破?
  • 从 OpenClaw 到 IoTDB Skills:时序数据库如何接入 AI Agent 世界?
  • 2026年热门的免开槽暗藏合页/多功能暗藏合页厂家推荐及选购指南 - 品牌宣传支持者
  • 2026年防火卷帘门厂家专业选型指南:特级/不锈钢/防爆/工业/提升式防火卷帘门供应商推荐——河南中能盾消防科技有限公司深度解析 - 品牌推荐官
  • 收藏!小白程序员快速入门LLM Agent,解锁AI智能体强大能力
  • 2026年质量好的斜挂式无障碍升降机/轮椅升降机高口碑厂家推荐(评价高) - 品牌宣传支持者
  • 生病带薪摸鱼
  • 2026年口碑好的甲油胶美甲灯/便携美甲灯厂家推荐及选择指南 - 品牌宣传支持者
  • 2026年口碑好的二段力液压玻璃合页/缓冲液压玻璃合页厂家推荐及选购指南 - 品牌宣传支持者
  • 喝酒后怎么养护细胞?NMN哪个品牌效果最好?2026年十大抗衰效果威验证 - 速递信息
  • 沃尔玛购物卡闲置不用?正确处理方式全攻略 - 团团收购物卡回收
  • windows上excel运行macro之后出现错误
  • 闲置购物卡消费券额度别愁,一站式合规处理方案来了 - 团团收购物卡回收
  • 瑞祥商联卡闲置变现,这些安全细节千万别大意 - 团团收购物卡回收
  • 手里的京东 E 卡用不上?合规处理方式全攻略 - 团团收购物卡回收
  • 永辉购物卡闲置不用?合规变现方法一文讲透 - 团团收购物卡回收
  • 2026年2月别墅电梯公司权威推荐,复式别墅专用电梯选型指南 - 品牌鉴赏师
  • 2026高活性NMN十佳品牌深度拆解哪款值得长期吃?从成分、技术、临床数据全维度测评 - 速递信息
  • 2026年评价高的垂直式残疾人升降平台/升降平台高评分品牌推荐(畅销) - 品牌宣传支持者
  • 全场景人事外包精选,适配上海临时+外资企业人事外包 - 包罗万闻
  • 2026年靠谱的广场砖/庭院广场砖厂家推荐及采购参考 - 品牌宣传支持者
  • 分期乐购物额度变现,这些合规禁区绝对不能闯 - 团团收购物卡回收
  • 2026年评价高的传统兰州牛肉拉面/正宗兰州牛肉拉面人气优选推荐加盟 - 品牌宣传支持者
  • 2026年口碑好的环保设备/好氧颗粒污泥环保设备厂家选购全指南(完整版) - 品牌宣传支持者
  • 支付宝消费券领了用不上?合规处理方法看这篇就够了 - 团团收购物卡回收