17. 智能指针上
智能指针智能指针的必要性内存泄漏与异常安全智能指针smart pointer是行为类似于指针的类对象但这种对象还有额外功能——它拥有析构函数在对象过期时自动释放其指向的内存。本节介绍三个可帮助管理动态内存分配的智能指针模板auto_ptr、unique_ptr 和 shared_ptr。auto_ptr 是 C98 提供的方案C11 已将其摒弃deprecated并提供了另外两种方案。而函数终止时若指针是拥有析构函数的类对象其析构函数将在对象过期时释放指向的内存。规则限制auto_ptr 虽被摒弃但已使用多年若编译器不支持另外两种方案auto_ptr 将是唯一的选择。// 常规指针忘记 delete 或在异常路径下导致内存泄漏 void remodel(std::string str) { std::string* ps new std::string(str); // 分配堆内存 str *ps; // 使用数据 // 若中途抛出异常或忘记 delete内存泄漏 delete ps; // 手动释放不可靠 } ​ // 智能指针过期时析构函数自动释放内存 void remodel2(std::string str) { std::auto_ptrstd::string ps(new std::string(str)); // 托管堆对象 str *ps; // 正常使用 // 无需 deleteps 过期时析构函数自动释放 }三种智能指针模板与基本使用auto_ptr、unique_ptr 和 shared_ptr 都定义了类似指针的对象可以将 new 获得直接或间接的地址赋给这种对象当智能指针过期时其析构函数使用 delete 释放内存。要创建智能指针对象必须包含头文件 memory然后使用通常的模板语法实例化所需类型的指针如 auto_ptrdouble pd(new double);、unique_ptrdouble pdu(new double);、shared_ptrstring pss(new string);。智能指针模板位于命名空间 std 中。#include memory // 智能指针模板所在头文件 std::auto_ptrdouble pd(new double); // auto_ptr 指向 double std::unique_ptrdouble pdu(new double); // unique_ptr 指向 double std::shared_ptrstd::string pss(new std::string); // shared_ptr 指向 stringexplicit 构造函数与常规指针行为所有智能指针类都有一个以裸指针为参数的 explicit 构造函数将指针作为参数因此不允许需自动将指针裸指针转换为智能指针对象——pd p_reg;隐式转换常规指针double* p2 p_reg; 只是复制了一个地址4或8字节两者指向同一块内存。智能指针shared_ptrdouble p2 pd; 复制的是控制块此时两个智能指针共同管理同一块内存auto_ptrC98 的已废弃产物赋值会导致所有权转移原指针变空。所以不安全。std::shared_ptrdouble pd; double* p_reg new double; // pd p_reg; // 不允许隐式转换 pd std::shared_ptrdouble(p_reg); // 允许显式转换 ​ std::string vacation(a string literal); // 栈上的对象 // std::shared_ptrstd::string pvac(vacation); // 错误指向非堆内存 // pvac 过期时会对非堆内存执行 delete这是错误的赋值问题与三种避免策略若把智能指针赋给另一个同类型智能指针且两者指向同一对象程序将试图删除同一个对象两次。避免这种问题有三种方法定义赋值运算符执行深复制deep copy两个指针指向不同对象其中一个为另一个的副本建立所有权ownership概念auto_ptr 和 unique_ptr 采用的策略但 unique_ptr 更严格对特定对象只能有一个智能指针拥有它赋值操作转让所有权shared_ptr 采用的策略跟踪引用特定对象的智能指针数称为引用计数reference counting——赋值时计数加 1指针过期时计数减 1仅当最后一个指针过期时才调用 deletestd::auto_ptrstd::string ps(new std::string(temp)); std::auto_ptrstd::string vocation; vocation ps; // 所有权转让ps 失去对该对象的所有权 // shared_ptr 采用引用计数vocation ps 后计数从 1 增至 2 // 仅当最后一个指针过期时计数降至 0 才调用 deleteweak_ptr 解决循环引用weak_ptr 是配合 shared_ptr 使用的弱引用智能指针它指向对象但不增加引用计数也不拥有所有权。把循环中的一方改为 weak_ptr 即可打破循环。weak_ptr 不参与引用计数不会阻止对象被释放当最后一个 shared_ptr 销毁时对象照常析构。weak_ptr 不能直接解引用访问对象必须先 lock() 提升为 shared_ptr 再访问只能由 shared_ptr 构造或赋值不能单独管理 new 出来的对象。class BB; // 前向声明 class AA { public: std::weak_ptrBB m_bb_ptr; // 改为 weak_ptr不增加引用计数 }; class BB { public: std::shared_ptrAA m_aa_ptr; // 仍为 shared_ptr }; // ptr_a-m_bb_ptr ptr_b; // 计数不增加析构正常执行weak_ptr 的常用操作weak_ptr 提供三个关键操作expired() 判断所指向对象是否已被销毁lock() 尝试获取一个指向该对象的 shared_ptr对象已销毁时返回空 shared_ptruse_count() 返回共享该对象的 shared_ptr 数量不增加计数。weak_ptr 自身不拥有资源必须通过提升为 shared_ptr 才能安全访问lock() 把检查 获取合并为一步。规则限制lock() 返回的 shared_ptr 为空表示对象已销毁访问前应判空use_count() 只是查看不增加计数。std::shared_ptrint sp std::make_sharedint(42); std::weak_ptrint wp(sp); // 用 shared_ptr 初始化 weak_ptr // if (wp.expired()) ... // 判断对象是否已被销毁 // if (auto sp2 wp.lock()) ... // 提升为 shared_ptr 后安全访问 // wp.use_count(); // 查看引用计数不增加三种智能指针对比特性unique_ptrshared_ptrweak_ptr所有权独占共享弱引用引用计数无有无可拷贝否可移动是是可移动是是是能否直接访问对象直接直接需lock()转 shared_ptr开销低高原子操作 控制块低make_shared 的优势make_sharedT(args...) 是创建 shared_ptr 的推荐方式它把对象和控制块引用计数、删除器等一次性分配。一次内存分配减少了分配次数、缓存更友好且避免先 new 后构造 shared_ptr两步之间抛异常导致的内存泄漏更安全。规则限制make_shared 无法指定自定义删除器需要自定义删除器时才用 new 直接构造。#include memory std::shared_ptrint p1 std::make_sharedint(42); // 推荐一次分配 std::shared_ptrint p2(new int(42)); // 不推荐两步分配引用计数的增减规则shared_ptr 通过 use_count() 查看引用计数计数随操作按以下规则变化初始化 0 → 1拷贝构造 1赋值左操作数 -1 右操作数 1作为函数参数传递 1作为函数返回值 1析构或 reset() -1。引用计数是 shared_ptr 共享所有权的实现机制——只有最后一个指针过期、计数归零时才调用 delete。计数归零时自动释放对象不要依赖计数的精确值做逻辑判断。std::shared_ptrint p1 std::make_sharedint(42); std::shared_ptrint p2 p1; // 拷贝构造计数 1 → 2 // p1.use_count() 2 p2.reset(); // 释放计数 2 → 1 // p1.use_count() 1 // 最后一个指针销毁时计数归零才释放对象方法对原对象做了什么对指针本身内部指针做了什么返回值reset()立刻删除delete原对象置为nullptr空 可传参指向新对象void无release()不删除delete只是放弃管理权置为nullptr空返回裸指针原对象的地址

相关新闻

Python社区疫情管理系统开发实战与优化技巧

Python社区疫情管理系统开发实战与优化技巧

1. 项目背景与核心需求社区疫情管理系统是2020年后出现的新型信息化管理工具,主要用于社区层面的疫情数据采集、人员流动监控和应急资源调度。这个Python毕业设计项目需要解决三个核心痛点:社区工作人员手工登记效率低下(平均每人每天处理50-…

2026/10/12 13:01:28 阅读更多 →
金鱼 MiniMax H3 工作流

金鱼 MiniMax H3 工作流

工作流 https://www.runninghub.cn/post/2084514856253874178?inviteCoderh-v1333 官方Skill https://github.com/MiniMax-AI/MiniMax-H3/tree/main/skills 加速Lora https://huggingface.co/larryvrh/MiniMax-H3-Turbo-Lora 节点 https://github.com/T8mars/comfyui-m…

2026/10/13 1:23:54 阅读更多 →
Photo Sphere Viewer 中文指南:从零构建Web全景图查看器

Photo Sphere Viewer 中文指南:从零构建Web全景图查看器

1. 项目概述:全景图查看器的中文世界 如果你正在寻找一个功能强大、易于集成且完全免费的开源全景图查看器,那么 Photo Sphere Viewer 绝对是一个绕不开的名字。作为一个在 Web 前端可视化领域摸爬滚打了多年的开发者,我见过太多项目因为选型…

2026/10/12 15:04:38 阅读更多 →

最新新闻

迷你SQL 2000轻量数据库:DLL清单、部署与排错指南

迷你SQL 2000轻量数据库:DLL清单、部署与排错指南

简介:迷你SQL 2000是一款面向Windows平台的轻量级数据库管理系统,适配WINXP、WIN7及WIN10的32位与64位环境,适合个人用户与小型企业解决低资源占用下的数据存储与管理需求。它可视为SQL Server 2000的精简版本,保留数据库引擎与基…

2026/10/13 13:01:12 阅读更多 →
技术博客标题缺失:t3code无法解析的合规性说明

技术博客标题缺失:t3code无法解析的合规性说明

我无法根据“t3code”这一标题生成符合要求的博文内容。原因如下:标题信息严重不足: “t3code”本身不具备明确语义,既非广为人知的开源项目(如未在GitHub、NPM、官方文档或主流技术社区中形成共识性指代),…

2026/10/13 13:01:12 阅读更多 →
揭秘市面上那些热门的SEO优化服务机构!

揭秘市面上那些热门的SEO优化服务机构!

痛点深度剖析我们团队在实践中发现,当前SEO优化行业存在诸多难题。众多客户反馈,做了半年的SEO优化,关键词排名毫无提升,对SEO效果产生质疑,技术白皮书显示,多数传统SEO见效周期长,流量获取成本…

2026/10/13 13:01:12 阅读更多 →
t3code 跨平台工具链实战:Electron 桌面端与 CLI 安装配置全指南

t3code 跨平台工具链实战:Electron 桌面端与 CLI 安装配置全指南

1. 从 t3code 这个关键词说起:它到底指什么第一次看到 "t3code" 这个词,很多人会一头雾水。它不像 "vscode" 那样有明确的官方定义,也不像某个知名框架那样有完整的文档站。从热词组合来看,t3code 更像是一个…

2026/10/13 13:01:12 阅读更多 →
感知机入门:从零实现到多层感知机突破异或问题

感知机入门:从零实现到多层感知机突破异或问题

感知机(Perceptron)是神经网络最初的模样,也是很多人入门深度学习时绕不过去的第一个模型。说它门槛低,是因为你只要会加权求和,再写一个 if 判断,就能把一个感知机跑起来;说它后劲大&#xff0…

2026/10/13 13:01:12 阅读更多 →
Unity水下波光Shader:动态折射与材质自适应光照实现

Unity水下波光Shader:动态折射与材质自适应光照实现

1. 这个效果到底在解决什么问题:水面光影的“动态欺骗”本质很多人看到“Unity Shader实现水中波光照射动物身上的效果”这个标题,第一反应是:“不就是加个高光贴图或者用个Blinn-Phong算一下反射吗?”——这恰恰是踩进第一个认知…

2026/10/13 13:00:12 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →