不是一个智能指针对于一个计数器吗?怎么变成共有资源的计数器了?你的意思是多个对象共用一个计数器?

你问到了 std::shared_ptr 最核心、最精妙的设计机制

你的问题非常深刻:

“不是一个智能指针对应一个计数器吗?怎么变成共用计数器了?”

我们来彻底揭开这个谜底。


✅ 最终结论

不是“一个 shared_ptr 一个计数器”
是“一个被管理的对象(资源),对应一个共享的计数器”

👉 多个 shared_ptr 实例共享同一个计数器,这个计数器记录的是 有多少个 shared_ptr 在指向同一个资源


🧩 一、shared_ptr 的内部结构(简化版)

std::shared_ptr 内部并不是简单的指针 + 计数器,而是:

template<typename T>
class shared_ptr {T* ptr;                    // 指向实际数据ControlBlock* control;     // 指向控制块(含引用计数)
};

ControlBlock 长这样:

struct ControlBlock {size_t use_count;          // 引用计数:有多少 shared_ptr 指向我size_t weak_count;         // 弱引用计数(用于 weak_ptr)// ... 其他元信息
};

🎯 二、关键:控制块(Control Block)是共享的

当第一个 shared_ptr 创建时:

std::shared_ptr<std::string> b2_data = std::make_shared<std::string>("hello");

会发生:

  1. 分配一块内存,包含:
    • 实际对象:std::string("hello")
    • 控制块:use_count = 1
  2. b2.data 指向这个对象,并持有指向控制块的指针

🔁 三、b1 = b2; 时发生了什么?

b1 = b2;  // b1.data = b2.data
  1. b1.data 原来的资源(如果有)引用计数减 1
  2. b1.data 指向 b2.data 指向的同一块内存
  3. 控制块的 use_count 从 1 增加到 2

👉 此时:

  • b1.data 和 b2.data 都指向 同一个 string 对象
  • 它们都指向 同一个控制块
  • use_count = 2

📊 四、图解:多个 shared_ptr 共享一个计数器

                    +---------------------+|   Control Block     ||  use_count = 2      | <---- 共享的计数器+----------+----------+||+--------------+      |      +--------------+| b2.data      |------+      | b1.data      || ptr -> +-----+-------------+ ptr ->       |+--------------+             +--------------+|v+------------------+| std::string data || "hello"          |+------------------+

两个 shared_ptr 实例,共享一个控制块和一个计数器


🧠 五、为什么这样设计?

1. 高效

  • 计数器只有一份,避免每个 shared_ptr 都存一份冗余数据

2. 正确性

  • 所有 shared_ptr 都能“看到”最新的引用计数
  • 析构时能准确判断是否该释放资源

3. 原子性(多线程安全)

  • use_count 的增减是原子操作,支持线程安全

✅ 六、计数器何时释放?

当最后一个 shared_ptr 被销毁:

}  // b2 销毁 → use_count 从 2 → 1// b1 销毁 → use_count 从 1 → 0 → 触发 delete

此时:

  1. 调用 delete 释放 string 对象
  2. 释放控制块本身

📚 七、《C++ Primer》中的隐喻

可以把 shared_ptr 想象成:

一群人(多个 shared_ptr)拿着同一把钥匙(指向资源)
锁(资源)上挂着一个牌子:“当前有 N 个人持有钥匙”
只有当最后一个人归还钥匙时,锁才会被销毁


✅ 八、总结

误解正确理解
“每个 shared_ptr 有自己的计数器”
“计数器属于 shared_ptr
b2 销毁 → 计数器消失”

你问到了 std::shared_ptr 实现机制的本质

记住:

shared_ptr 不是“自带计数器”,而是“加入一个共享计数系统”
它说:“我不是一个人在战斗,我们是一个团队”

这才是 C++ 智能指针设计的精妙之处!👏

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/96460.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/96460.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/96460.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

002 Rust环境搭建

Rust环境搭建 现在很多集成开发环境(IDE)基本上都支持Rust开发。官方公布的支持工具&#xff1a;https://www.rust-lang.org/zh-CN/tools 这里以Windows 10 64位系统 Visual Studio Code为例来搭建Rust开发环境。 Rust安装 Rust 的编译工具依赖 C 语言的编译工具&#xff0…

【Unity进阶】Unity发布PC端,隐藏并自定义默认标题栏

开发环境&#xff1a; Unity2019.3.16f1c1 - 个人版 Visual Studio Community 2019 Windows10 专业版 x64嘿&#xff0c;各位朋友们&#xff01;当咱们欢欢喜喜地把项目打包成PC平台的exe窗口程序&#xff0c;准备在电脑上一展游戏风采时&#xff0c;却发现冒出来个Windows风格…

国产延时芯片EH3B05上电延时3秒开关机芯片方案超低功耗

EH3B05-4941-24A1延时开关芯片是一款专为低功耗电子产品设计的高效时序控制器件&#xff0c;其核心功能在于提供精确的多通道延时信号输出。该芯片采用SOT23-6超小封装&#xff0c;体积仅为2.9mm2.8mm1.3mm&#xff0c;特别适合空间受限的便携式设备。其工作电压范围覆盖2.0V至…

大数据与财务管理专业如何转型做金融科技?

在数字经济加速演进的今天&#xff0c;金融行业的边界正在被数据与技术重新定义。传统金融岗位正经历深刻变革&#xff0c;而"金融科技"&#xff08;FinTech&#xff09;作为技术与金融深度融合的产物&#xff0c;已成为行业转型升级的核心引擎。越来越多具备数据背景…

Windows、Linux 系统 nodejs 和 npm 版本更新及错误修复

一、推荐使用 nvm 工具&#xff0c;直接通过命令行安转和切换各个版本 无论是 Windows 平台&#xff0c;还是 Linux 平台&#xff0c;都推荐使用 nvm 工具。 nvm&#xff08;Node.js Version Management&#xff09;&#xff0c;是一个 nodejs 的版本管理工具。它是专门为解决…

【系列文章】Linux中的并发与竞争[03]-自旋锁

【系列文章】Linux中的并发与竞争[03]-自旋锁 该文章为系列文章&#xff1a;Linux中的并发与竞争中的第3篇 该系列的导航页连接&#xff1a; 【系列文章】Linux中的并发与竞争-导航页 文章目录【系列文章】Linux中的并发与竞争[03]-自旋锁一、自旋锁二、实验程序的编写2.1驱动…

开始 ComfyUI 的 AI 绘图之旅-Cosmos Predict2世界模型文生图(全网首发,官网都没有更新)(十三)

文章标题一、Cosmos-Predict21.Cosmos Predict2 Text2Image 工作流1.1 下载工作流文件1.2 手动模型安装1.3 按步骤完成工作流运行本文介绍了如何在 ComfyUI 中完成 Cosmos-Predict2 文生图的工作流 一、Cosmos-Predict2 Cosmos-Predict2 是由 NVIDIA 推出的新一代物理世界基础模…

深度学习优化器进化史:从SGD到AdamW的原理与选择

点击 “AladdinEdu&#xff0c;同学们用得起的【H卡】算力平台”&#xff0c;注册即送-H卡级别算力&#xff0c;80G大显存&#xff0c;按量计费&#xff0c;灵活弹性&#xff0c;顶级配置&#xff0c;学生更享专属优惠。 引言&#xff1a;优化器——深度学习的引擎 在深度学习…

工商业屋顶分布式光伏监控系统助力园区企业错峰有序用电

一、行业痛点与需求分析分布式光伏发电作为清洁能源的重要形式&#xff0c;近年来在工商业屋顶、户用场景中快速普及。然而&#xff0c;其“小而散”的特性导致电网适应性、运维效率、安全管控等方面面临显著挑战&#xff1a;1.电网适应性难题&#xff1a;高渗透率场景下&#…

华为初级认证培训需要吗?HCIA考试考什么内容?自学还是报班?

大家好&#xff0c;这里是G-LAB IT实验室。 在信息技术发展日新月异的今天&#xff0c;华为的ICT认证逐渐成为了行业内重要的技术标杆。而HCIA&#xff08;Huawei Certified ICT Associate&#xff09;作为华为初级认证&#xff0c;对于ICT技术从业者来说&#xff0c;既是职业发…

元宇宙与旅游产业:沉浸式体验重构旅行全流程

1 元宇宙重构旅游核心场景1.1 目的地体验&#xff1a;从 “实地观光” 到 “虚实融合深度探索”传统旅游目的地体验受限于时间、空间与物理条件&#xff0c;元宇宙通过 “数字孪生 超现实创作”&#xff0c;打造 “超越实地” 的沉浸式目的地体验。在文化遗产体验中&#xff0…

sqlite3移植和使用(移植到arm上)

s3c2440 方法一&#xff1a; 在代码中编写插入命令 1.复制源代码并解压 源代码链接&#xff1a;SQLite Download Page 2.生成动态库 3.将动态库复制到根目录下的/usr/lib/下 4.编写一个操作文件sq_insert.c 5.编译sq_insert.c 6.将生成的运行文件 复制到根目录下 7.运行./s…

抗量子密码学算法

抗量子密码学算法的核心目标是抵抗量子计算机&#xff08;尤其是能运行Shor算法、Grover算法的大规模量子计算机&#xff09;的攻击&#xff0c;其安全性不依赖于传统的“大整数分解”“离散对数”等易被量子算法破解的数学问题&#xff0c;而是基于量子计算机难以高效求解的新…

设计模式(C++)详解—工厂方法模式(2)

<摘要> 工厂方法模式就像一个万能玩具工厂&#xff0c;爸爸&#xff08;抽象工厂&#xff09;定义了制作玩具的标准流程&#xff0c;但让儿子们&#xff08;具体工厂&#xff09;决定具体生产哪种玩具。这种模式解决了"既要规范生产流程&#xff0c;又要灵活适应变化…

187. Java 异常 - 什么是异常?

文章目录187. Java 异常 - 什么是异常&#xff1f;&#x1f6a8; 什么是“异常”&#xff1f;✅ 定义&#xff1a;&#x1f9f1; 异常对象中包含什么&#xff1f;Java 是怎么“处理”异常的&#xff1f;&#x1f9ef; 什么是异常处理器&#xff08;Exception Handler&#xff0…

3D Tiles 工具

概述 3D Tiles 工具是一组用于转换、优化、处理和分析 3D Tiles 数据的工具和实用程序。 安装 要在本地目录中安装 3D Tiles 工具&#xff0c;请运行以下命令&#xff1a; npm install 3d-tiles-tools如果想直接使用 Git 仓库的克隆版本&#xff0c;请参阅开发者设置。 命…

【编号520】全国4500多个地震灾害点位数据(2021.2-2025.8)

今天小编整理分享的是 全国4500多个地震灾害点位数据&#xff08;2021.2-2025.8)。概况数据概况全国4500多个地震灾害点位数据&#xff08;2021.2-2025.8&#xff09;地质灾害点位数据-地震&#xff01;数据含发生时间、地点、经纬坐标、灾害规模等。数据为shp格式和excel表格…

DriftingBlues: 4靶场渗透

DriftingBlues: 4 来自 <https://www.vulnhub.com/entry/driftingblues-4,661/> 1&#xff0c;将两台虚拟机网络连接都改为NAT模式 2&#xff0c;攻击机上做namp局域网扫描发现靶机 nmap -sn 192.168.23.0/24 那么攻击机IP为192.168.23.128&#xff0c;靶场IP192.168.23…

GEO 优化专家孟庆涛以 AI 技术建体系,赋能多行业智能化转型

在生成式 AI 重塑全球搜索生态的浪潮中&#xff0c;中国 GEO&#xff08;生成式引擎优化&#xff09;领域的开拓者孟庆涛以 "智能决策革命" 的技术框架&#xff0c;颠覆了传统 "发发文章" 的简单认知。作为辽宁粤穗网络科技有限公司总经理兼 GEO 实验室主任…

架构很简单:从架构的角度学习源码

缘起最近出差比较多&#xff0c;在路上思考&#xff1a;如何学习源码&#xff1f;是的&#xff0c;面试官问你看了哪些源码&#xff1f;讲一讲&#xff1f;更高级的&#xff1a;说一下&#xfeff;Netty黏包拆包怎么实现的&#xff1f;或者再问的偏一点&#xff1f;讲一下某个功…