如何用c++从零实现一个简单的shared_ptr 智能指针工作原理【深入剖析】


shared_ptr的核心设计目标是自动管理堆内存生命周期,支持多引用共享并在最后一个引用销毁时自动释放资源;它通过独立的控制块记录强引用计数、删除器等信息,并确保控制块与对象内存协同分配和释放。

如何用c++从零实现一个简单的shared_ptr 智能指针工作原理【深入剖析】

shared_ptr 的核心设计目标

shared_ptr 要解决的核心问题是:**自动管理堆内存的生命周期,支持多份引用共享同一对象,并在最后一个引用销毁时自动释放资源**。它不是靠“记住所有指针”来实现,而是引入一个独立的、与托管对象分离的**控制块(control block)**,用来记录当前有多少 shared_ptr 指向该对象(引用计数),以及可选的删除器、分配器等信息。

控制块结构与内存布局

标准 shared_ptr 通常将控制块和托管对象分开分配(默认情况下),但为简化实现,常见教学版采用“一块内存同时存放控制块 + 对象”的方式(即使用 placement new)。控制块至少需包含:

  • weak_count:弱引用计数(用于 weak_ptr,本例暂略)
  • shared_count:强引用计数(即当前有多少个 shared_ptr 指向该对象)
  • deleter:自定义删除逻辑(如 delete、delete[]、lambda 等),本例先用函数指针或 std::function 封装
  • allocator:可选,本例忽略

关键点:控制块必须能通过托管对象地址反向找到自己(否则 reset 或析构时无法访问计数),所以一般把控制块放在对象之前,或用额外指针关联。教学实现中更常用的是「统一 new 一块内存,前 sizeof(control_block) 字节放控制块,后续放对象」。

构造、拷贝与赋值的引用计数逻辑

每次创建新的 shared_ptr(无论是通过 new 构造、拷贝构造,还是赋值),都要让控制块中的 shared_count 加 1;每次 shared_ptr 销毁(析构)或重置(reset),都要减 1;当 shared_count 减到 0,就调用 deleter 释放对象并销毁控制块。

立即学习“C++免费学习笔记(深入)”;

  • 构造(T* ptr):new 一块足够大的内存(sizeof(control_block) + sizeof(T)),在前部构造 control_block(shared_count=1),在后部 placement new 构造 T 对象
  • 拷贝构造 / 拷贝赋值:将源 shared_ptr 的控制块指针复制过来,并对 shared_count 原子地加 1(实际应 std::atomic,教学可用 int + 注释说明线程不安全)
  • 析构:对 shared_count 原子减 1;若结果为 0,则调用 deleter 释放对象,再 delete 控制块本身

注意:不能直接 delete ptr,因为 ptr 是对象地址,而控制块地址 = ptr - sizeof(control_block),需先算出控制块地址才能正确释放整块内存。

Brev AI Brev AI

Brev.ai:搭载Suno AI V3.5技术的免费AI音乐生成器

Brev AI 437 查看详情 Brev AI

关键成员函数与操作符重载

一个最小可行 shared_ptr 需支持:

  • get():返回原始指针(即对象地址)
  • operator->() 和 operator*():支持像原生指针一样访问成员和解引用
  • reset():放弃当前所有权,若原引用是最后一个,则立即释放;可接受新指针重绑定
  • use_count():返回当前 shared_count(调试用,非线程安全读取)
  • operator bool():判断是否持有有效对象(即 get() != nullptr)

所有这些操作都不修改所指对象,只影响控制块状态。例如 operator-> 直接返回保存的 raw_ptr;reset 则先尝试减少旧控制块计数,再按需初始化新控制块。

不复杂但容易忽略的细节

真正写起来会踩几个典型坑:

  • 控制块和对象的内存必须同一次分配(或确保能安全反查),否则 delete ptr 会漏掉控制块内存泄漏
  • deleter 必须能处理任意类型(包括数组、自定义释放逻辑),推荐用 type-erasure(如 void* + 函数指针)或模板成员函数封装
  • 拷贝/移动语义要严格区分:拷贝增加计数,移动应转移所有权(源变为 nullptr,计数不减),C++11 后必须实现移动构造和移动赋值
  • 空 shared_ptr(如 default 构造)必须保证 get()==nullptr、use_count()==0、析构无副作用

掌握这些,你就看清了 shared_ptr 不是“魔法”,而是一套围绕控制块精心设计的引用计数协议。标准库实现更复杂(支持别名构造、定制分配器、weak_ptr 协同等),但骨架一致。

以上就是如何用c++++从零实现一个简单的shared_ptr 智能指针工作原理【深入剖析】的详细内容,更多请关注其它相关文章!


# 如何使用  # 江苏标准网站建设市面价  # 演出营销推广  # 无锡seo哪家技术好  # 怎么做视频营销网站推广  # 了解专业网站推广的渠道  # 钻石展位的营销推广  # 强大seo方案  # 章丘网站建设教程  # seo做不动了  # 南宁律师网站建设  # 什么用  # 字节  # 尼克  # 可选  # 自定义  # 数据结构  # 本例  # 并在  # 工作原理  # 如何用  # red  # 标准库  # c++ 


相关栏目: 【 Google疑问12 】 【 Facebook疑问10 】 【 优化推广96088 】 【 技术知识133117 】 【 IDC资讯59369 】 【 网络运营7196 】 【 IT资讯61894


相关推荐: 如何使用CSS Grid实现“大方块左侧,小方块右侧垂直堆叠”的水平布局  word文档中的分隔符有哪些不同类型和用途_Word分隔符类型与用途方法  怎样设置开机后自动运行某个程序_Windows启动文件夹与任务计划【自动化】  yy漫画登录页面官方入口_yy漫画在线阅读网址入口  vivo手机视频通话美颜怎么设置_vivo视频通话美颜开启方法  支付宝如何解绑云闪付_支付宝与云闪付账户关联解除方法  《红果免费短剧》下载观看方法  《腾讯相册管家》注销账号方法  J*aScript与HTML元素交互:图片点击事件与链接处理教程  c++如何链接Boost库_c++准标准库的集成与使用  Lar*el 关联查询:同时筛选父表与子表数据的高效策略  《书耽》更换手机号方法  店铺如何关联视频号推广?视频号推广有什么用?  《雅迪智行》用手机开锁方法  《优志愿》修改手机号方法  《淘宝联盟》推广自己的店铺方法  百度网盘如何设置上传限额  《海底捞》点外卖方法  使用逻辑应用(Logic Apps)自动处理邮件附件中的XML到Excel  《糖豆》添加舞曲方法  芒果TV官网登录入口 芒果TV官方网站登录入口  VB表达式书写规则解析  C++中的explicit关键字有什么作用_C++类型转换控制与explicit使用  todesk如何添加信任设备_todesk信任设备设置教程  Win10关闭UAC用户账户控制的方法 Win10降低安全提示等级【技巧】  抖音视频如何添加标题?添加标题有哪些好处?  Fedora怎么安装 Fedora Workstation安装步骤  B站怎么开|直播| B站|直播|申请需要什么条件【新手必看】  如何在Podman容器中运行Composer_Docker替代品Podman的PHP与Composer容器化实践  英雄联盟争者留名活动介绍  京东物流快递破损了怎么办_京东快递破损理赔流程  苹果自助维修计划支持哪些设备机型  顺丰快递收费标准查询_如何查看顺丰最新收费价格  夸克浏览器资源嗅探怎么用 夸克浏览器网页资源下载技巧【教程】  圆通快递官网入口查询单号 手机版官方查询入口  Word 2003字体大小设置方法  怎样让Windows 11的开始菜单恢复经典样式_Open-Shell工具使用指南【怀旧】  Win11怎么设置分辨率 Win11显示设置调整分辨率及刷新率修改  电脑没有声音了怎么办 电脑声音问题的全面排查与修复指南【详解】  火柴人战争网页版在线玩  WooCommerce购物车:强制显示所有交叉销售商品教程  深入理解Python对象引用与链表属性赋值  搜狗浏览器如何查找页面中的文字 搜狗浏览器Ctrl+F页面搜索功能  J*aScript大数运算_BigInt使用指南  店铺如何做视频号推广?做视频号推广有用吗?  发布小红书怎么屏蔽粉丝?屏蔽粉丝能看到吗?  Excel如何快速合并单元格内容_Excel文本合并与函数操作技巧  iCloud官方网站 iCloud网页版在线登录入口  手机耗电快是什么原因 延长手机电池续航时间的设置方法【详解】  5G和6G的连接密度有什么区别 6G每平方公里能连接多少设备 

 2025-12-20

了解您产品搜索量及市场趋势,制定营销计划

同行竞争及网站分析保障您的广告效果

点击免费数据支持

提交您的需求,1小时内享受我们的专业解答。

运城市盐湖区信雨科技有限公司


运城市盐湖区信雨科技有限公司

运城市盐湖区信雨科技有限公司是一家深耕海外推广领域十年的专业服务商,作为谷歌推广与Facebook广告全球合作伙伴,聚焦外贸企业出海痛点,以数字化营销为核心,提供一站式海外营销解决方案。公司凭借十年行业沉淀与平台官方资源加持,打破传统外贸获客壁垒,助力企业高效开拓全球市场,成为中小企业出海的可靠合作伙伴。

 8156699

 13765294890

 8156699@qq.com

Notice

We and selected third parties use cookies or similar technologies for technical purposes and, with your consent, for other purposes as specified in the cookie policy.
You can consent to the use of such technologies by closing this notice, by interacting with any link or button outside of this notice or by continuing to browse otherwise.