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/8/11 2:49:10 阅读更多 →
金鱼 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/8/11 2:49:10 阅读更多 →
Photo Sphere Viewer 中文指南:从零构建Web全景图查看器

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

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

2026/8/11 2:49:10 阅读更多 →

最新新闻

如何实现拼多多自动回复与客服自动化?无人值守订单处理,日发5000单零差错

如何实现拼多多自动回复与客服自动化?无人值守订单处理,日发5000单零差错

如何实现拼多多自动回复与客服自动化?无人值守订单处理,日发5000单零差错 说句掏心窝的话,做店群的,工具选对了事半功倍。拼多多的自动回复与客服,是店群运营中最耗人力也最容易出错的环节。 店群客服是纯人力消耗战…

2026/8/11 3:42:28 阅读更多 →
深圳企业服务器 RAID 崩溃应急恢复全流程:从宕机到数据起死回生的 24 小时实录

深圳企业服务器 RAID 崩溃应急恢复全流程:从宕机到数据起死回生的 24 小时实录

摘要:在深圳制造、电商、科创企业的机房中,RAID 阵列承载着 ERP、MES、财务库、订单业务等核心数据。即便 RAID 自带冗余,仍可能遭遇多盘掉线、RAID 卡故障、坏道扩散、意外断电、固件损坏。一旦阵列整体崩溃,每一小时停机都是直接…

2026/8/11 3:42:28 阅读更多 →
自用学习笔记 C语言基础篇

自用学习笔记 C语言基础篇

C基础 ver.26/08/10 1.C语言的基础概念 C语言支持结构化编程,强调程序逻辑的清晰、模块化和易维护。 C语言不完全依赖于平台,具有良好的可移植性,C语言编写的程序可以在不同的平台上编译并运行,只需要进行一些小的调整或重新编译…

2026/8/11 3:42:28 阅读更多 →
如何用抖音下载器快速保存直播回放与批量下载内容:完整入门指南

如何用抖音下载器快速保存直播回放与批量下载内容:完整入门指南

如何用抖音下载器快速保存直播回放与批量下载内容:完整入门指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallb…

2026/8/11 3:42:28 阅读更多 →
ETL 管道

ETL 管道

1. 什么是 ETL 管道ETL(Extract、Transform、Load)即提取、转换和加载,是一种用于数据处理的数据工程框架。在 RAG(Retrieval Augmented Generation,检索增强生成)应用中,ETL 管道负责将企业原始…

2026/8/11 3:42:28 阅读更多 →
光刻显影缺陷:桥连/残留/塌陷的排查

光刻显影缺陷:桥连/残留/塌陷的排查

一、背景故事:ADI缺陷率一夜翻了三倍六月的一个周一早上,光刻区主管脸色铁青地站在晨会白板前:周末两天,KLA扫描的ADI(光刻后检查)缺陷密度从平时的每平方厘米零点一翻到了零点三,而且缺陷类型分…

2026/8/11 3:41:27 阅读更多 →

日新闻

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南

如何用Video2X实现专业级视频画质提升:AI视频增强完整指南 【免费下载链接】video2x A machine learning-based video super resolution and frame interpolation framework. Est. Hack the Valley II, 2018. 项目地址: https://gitcode.com/GitHub_Trending/vi/v…

2026/8/11 0:00:02 阅读更多 →
前后端分离项目中控制台与接口工具数据差异排查指南

前后端分离项目中控制台与接口工具数据差异排查指南

1. 问题现象解析:控制台与Apifox的数据差异 最近在调试一个前后端分离项目时,遇到了一个典型问题:后端服务在本地开发环境控制台能正常输出查询数据,但通过Apifox测试时却返回空结果。这种"控制台有数据,接口工具…

2026/8/11 0:00:03 阅读更多 →
AI编程实战:从Claude Code踩坑到游戏开发入门

AI编程实战:从Claude Code踩坑到游戏开发入门

1. 从“AI能帮我做游戏”到“AI让我重新学编程”最近身边不少朋友,尤其是一些非技术背景、但对游戏开发有浓厚兴趣的朋友,都在问我同一个问题:“听说现在用Claude Code这种AI编程工具,小白也能做游戏了,是真的吗&#…

2026/8/11 0:00:03 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/11 1:08:05 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/11 1:08:05 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/11 1:08:05 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/10 17:07:33 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/11 1:08:06 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/10 17:07:33 阅读更多 →