完整教程:C/C++内置库函数(2):智能指针

news/2026/1/20 11:06:44/文章来源:https://www.cnblogs.com/ljbguanli/p/19505474

完整教程:C/C++内置库函数(2):智能指针

一、std::unique_ptr(独占式智能指针)

1. 核心特性

  • 独占所有权:同一时间只有一个 unique_ptr 指向某个对象,不可拷贝(copy),仅可移动(move);
  • 轻量级(无额外引用计数开销),效率接近裸指针;
  • 适用场景:单个所有者管理对象(如函数返回值、局部动态对象、容器元素)。

2. 定义方式:

定义形式说明
unique_ptr<T> ptr;定义空的 unique_ptr(不指向任何对象)
unique_ptr<T> ptr(已有裸指针);该裸指针必须是由new分配的,否则delete的时候报错

unique_ptr<T> ptr(new T);

std::unique_ptr<T[]> ptr(new T[N]);

绑定到动态分配的 T 类型对象(C++11 基础方式)

auto ptr = make_unique<T>(args);

auto ptr = std::make_unique<T[]>(N);

C++14 推荐方式(更安全,避免内存泄漏),args 是 T 的构造参数

3. 常用方法

方法功能
ptr.get()返回管理的裸指针(仅临时使用,避免长期持有)
ptr.release()释放所有权(返回裸指针,不会释放内存,需手动处理)
ptr.reset()释放当前对象内存,重置为空;reset(new T) 则释放旧对象,指向新对象
ptr.swap()交换两个 unique_ptr 管理的对象
operator*解引用,访问指向的对象(如 *ptr = 10;
operator->访问对象的成员(如 ptr->func();
#include 
#include  // 必须包含
// 自定义类示例
class Test {
public:Test(int v) : val(v) { std::cout << "Test 构造:" << val << "\n"; }~Test() { std::cout << "Test 析构:" << val << "\n"; }void show() { std::cout << "值:" << val << "\n"; }
private:int val;
};
int main() {// 1. 定义并初始化(C++11 方式)std::unique_ptr ptr1(new Test(10));ptr1->show(); // 访问成员函数// 2. C++14 推荐:make_unique(更安全,避免内存泄漏)auto ptr2 = std::make_unique(20);(*ptr2).show(); // 解引用访问// 3. 移动语义(唯一的“拷贝”方式)std::unique_ptr ptr3 = std::move(ptr1); // ptr1 变为空,ptr3 接管if (!ptr1) std::cout << "ptr1 已空\n";ptr3->show();// 4. 重置(释放旧对象,指向新对象)ptr3.reset(new Test(30)); // 旧对象(val=10)析构,指向 val=30 的新对象// 5. 释放所有权(返回裸指针,需手动 delete)Test* raw_ptr = ptr3.release();delete raw_ptr; // 必须手动释放,否则内存泄漏return 0; // 作用域结束,ptr2 自动析构(val=20 释放)
}

二、std::shared_ptr(共享式智能指针)

1. 核心特性

  • 共享所有权:多个 shared_ptr 可指向同一对象,通过引用计数管理;
  • 引用计数为 0 时,自动释放对象内存;
  • 可拷贝、可赋值,拷贝时引用计数 +1,析构 / 重置时引用计数 -1;
  • 适用场景:多个所有者共享同一对象(如容器、多线程共享资源)

2. 定义方式:

定义形式说明
shared_ptr<T> ptr;空的 shared_ptr
std::shared_ptr<T> ptr(已有裸指针);接管已存在的动态裸指针

shared_ptr<T> ptr(new T);

std::shared_ptr<T[]> ptr(new T[N]);

绑定动态对象(不推荐,存在内存泄漏风险)

auto ptr = make_shared<T>(args);

auto ptr = std::make_shared<T[]>(N);

推荐方式(更高效,内存分配一次,避免泄漏)

3. 常用方法

方法功能
ptr.use_count()返回当前引用计数(调试用)
ptr.unique()判断是否为唯一所有者(引用计数 == 1 时返回 true)
ptr.reset()释放当前对象的所有权(引用计数 -1),重置为空
ptr.lock()(weak_ptr 方法)尝试获取可用的 shared_ptr(非 expired 时有效)
ptr.expired()(weak_ptr 方法)判断所指对象是否已释放(引用计数 == 0)
(继承 unique_ptr)get()operator*operator-> 等
#include 
#include 
class Test {
public:Test(int v) : val(v) { std::cout << "Test 构造:" << val << "\n"; }~Test() { std::cout << "Test 析构:" << val << "\n"; }int val;
};
int main() {// 1. 推荐方式:make_sharedstd::shared_ptr ptr1 = std::make_shared(100);std::cout << "引用计数:" << ptr1.use_count() << "\n"; // 输出 1// 2. 拷贝:引用计数 +1std::shared_ptr ptr2 = ptr1;std::cout << "引用计数:" << ptr1.use_count() << "\n"; // 输出 2// 3. 赋值:ptr3 接管,引用计数 +1std::shared_ptr ptr3;ptr3 = ptr2;std::cout << "引用计数:" << ptr1.use_count() << "\n"; // 输出 3// 4. 重置:ptr3 释放所有权,引用计数 -1ptr3.reset();std::cout << "引用计数:" << ptr1.use_count() << "\n"; // 输出 2// 5. 唯一所有者判断ptr2.reset();std::cout << "是否唯一:" << ptr1.unique() << "\n"; // 输出 1(true)return 0; // ptr1 析构,引用计数 0,对象释放
}

三、std::weak_ptr(弱引用智能指针)

1. 核心特性

  • 弱引用:指向 shared_ptr 管理的对象,但不增加引用计数
  • 不拥有对象所有权,仅作为 “观察者”,避免 shared_ptr 的循环引用问题;
  • 无法直接访问对象,需通过 lock() 方法转为 shared_ptr 后使用。

2. 定义方式:

定义形式说明
std::weak_ptr<T> ptr;空初始化:ptr 不观察任何对象,expired() 返回 true
std::weak_ptr<T> ptr(shared_ptr对象);观察 shared_ptr 管理的对象,引用计数不变

#include 
#include 
// 循环引用问题场景
struct Node {// 错误:两个 shared_ptr 互相引用,引用计数永远不为 0,内存泄漏// std::shared_ptr next;// 正确:用 weak_ptr 避免增加引用计数std::weak_ptr next;~Node() { std::cout << "Node 析构\n"; }
};
int main() {std::shared_ptr node1 = std::make_shared();std::shared_ptr node2 = std::make_shared();// 互相引用node1->next = node2; // weak_ptr 赋值,node2 引用计数不变node2->next = node1; // weak_ptr 赋值,node1 引用计数不变// 尝试访问 weak_ptr 指向的对象(需 lock())std::shared_ptr temp = node1->next.lock();if (temp) {std::cout << "node1->next 有效\n";}return 0; // node1、node2 析构,引用计数 0,对象释放
}

四、总结:

智能指针所有权拷贝性引用计数核心场景
unique_ptr独占不可拷贝,可移动单个所有者、局部对象
shared_ptr共享可拷贝、可赋值多所有者、共享资源
weak_ptr可拷贝、可赋值解决 shared_ptr 循环引用

1. 禁止的操作

  • 不要将同一个裸指针赋值给多个 unique_ptr(会导致重复释放);
  • 不要用 get() 返回的裸指针手动 delete(智能指针会重复释放);
  • 避免 shared_ptr 循环引用(用 weak_ptr 解决);
  • 不要在多线程中直接修改 shared_ptr 本身(引用计数操作线程安全,但对象访问需加锁)。

2. 最佳实践

场景推荐智能指针
单个所有者管理对象unique_ptr
多个所有者共享对象shared_ptr
解决 shared_ptr 循环引用weak_ptr
动态数组unique_ptr<T[]>(C++11)/ shared_ptr<T[]>
函数返回动态对象unique_ptr(高效)

五、智能指针别的定义方式:

1. unique_ptr

定义形式说明注意事项(版本 / 风险)
std::unique_ptr<T> ptr;空初始化:ptr 不指向任何对象,ptr == nullptrC++11+;默认删除器 std::default_delete<T>
std::unique_ptr<T> ptr(nullptr);显式空初始化(等价于上一种)C++11+;可读性更强
std::unique_ptr<T> ptr(new T);绑定新动态分配的单个 T 类型裸指针C++11+;裸指针必须是 new 分配,避免重复接管
std::unique_ptr<T> ptr(已有裸指针);接管已存在的动态裸指针(如函数返回的裸指针)C++11+;裸指针必须是 new 分配,且仅能被一个 unique_ptr 接管
std::unique_ptr<T[]> ptr(new T[N]);绑定动态数组裸指针(数组版)C++11+;自动调用 delete[],支持下标访问 ptr[i]
auto ptr = std::make_unique<T>(args...);直接创建单个 T 对象并初始化(推荐)C++14+;更安全(避免内存泄漏),args 是 T 的构造参数
auto ptr = std::make_unique<T[]>(N);直接创建长度为 N 的 T 类型动态数组C++14+;数组元素默认初始化(如 int 数组值为 0)
auto ptr = std::make_unique<T[]>({v1, v2, ...});创建动态数组并初始化元素C++20+;仅支持固定初始值列表
std::unique_ptr<T> ptr(std::move(另一个unique_ptr));移动初始化:接管另一个 unique_ptr 的所有权C++11+;原 unique_ptr 变为空,不可拷贝仅可移动
std::unique_ptr<T, Deleter> ptr(new T, 自定义删除器);自定义删除器:替换默认的 delete 逻辑C++11+;删除器需满足可调用,如 std::function<void(T*)> 或 lambda
std::unique_ptr<T[], Deleter> ptr(new T[N], 自定义数组删除器);数组版 + 自定义删除器C++11+;删除器需适配数组(调用 delete[] 或自定义释放逻辑)
std::unique_ptr<T> ptr(std::auto_ptr<T>(std::move(ap)));从废弃的 auto_ptr 转换(兼容用)C++11+;auto_ptr 已废弃,仅用于老代码迁移

2. shared_ptr

定义形式说明注意事项(版本 / 风险)
std::shared_ptr<T> ptr;空初始化:ptr 不指向任何对象,引用计数 0C++11+;默认删除器 std::default_delete<T>
std::shared_ptr<T> ptr(nullptr);显式空初始化(等价于上一种)C++11+;可读性更强
std::shared_ptr<T> ptr(new T);绑定新动态分配的单个 T 类型裸指针C++11+;不推荐(存在内存泄漏风险),优先用 make_shared
std::shared_ptr<T> ptr(已有裸指针);接管已存在的动态裸指针C++11+;禁止将同一裸指针赋值给多个 shared_ptr(重复计数导致重复释放)
std::shared_ptr<T> ptr(new T[N], std::default_delete<T[]>());绑定动态数组(C++17 前需指定数组删除器)C++11+;C++17 后可省略删除器,默认支持数组
std::shared_ptr<T[]> ptr(new T[N]);数组版初始化(默认删除器支持数组)C++17+;支持下标访问 ptr[i]
auto ptr = std::make_shared<T>(args...);直接创建单个 T 对象并初始化(推荐)C++11+;内存分配更高效(一次分配对象 + 引用计数),args 是构造参数
auto ptr = std::make_shared<T[]>(N);直接创建长度为 N 的 T 类型动态数组C++20+;数组元素默认初始化
std::shared_ptr<T> ptr(std::move(另一个shared_ptr));移动初始化:接管另一个 shared_ptr 的所有权,引用计数不变C++11+;原 shared_ptr 变为空
std::shared_ptr<T> ptr(另一个shared_ptr);拷贝初始化:共享所有权,引用计数 +1C++11+;可拷贝是 shared_ptr 核心特征
std::shared_ptr<T> ptr(new T, 自定义删除器);自定义删除器:替换默认的 delete 逻辑C++11+;删除器不影响 shared_ptr 类型(类型擦除)
std::shared_ptr<T> ptr(std::unique_ptr<T>(std::move(up)));从 unique_ptr 转换:接管其所有权,引用计数设为 1C++11+;unique_ptr 必须移动,转换后变为空
std::shared_ptr<T> ptr(weak_ptr.lock());从 weak_ptr 转换:若对象未释放则获取 shared_ptr,否则返回空C++11+;需先判断 ptr 是否为空(避免悬空)

3. weak_ptr

定义形式说明注意事项(版本 / 风险)
std::weak_ptr<T> ptr;空初始化:ptr 不观察任何对象,expired() 返回 trueC++11+;无引用计数,不拥有对象所有权
std::weak_ptr<T> ptr(nullptr);显式空初始化(等价于上一种)C++11+;可读性更强
std::weak_ptr<T> ptr(shared_ptr对象);观察 shared_ptr 管理的对象,引用计数不变C++11+;核心用法(解决循环引用)
std::weak_ptr<T> ptr(另一个weak_ptr);拷贝初始化:观察同一个对象C++11+;引用计数不变
std::weak_ptr<T> ptr(std::move(另一个weak_ptr));移动初始化:观察同一个对象,原 weak_ptr 变为空C++11+;仅转移 weak_ptr 自身的资源,不影响被观察对象

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

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

相关文章

好写作AI|论文写作“敏捷开发”模式:别再当“瀑布模型”的炮灰了!

你的论文写作流程&#xff0c;是不是还停留在“憋大招-崩溃-通宵-交初稿-被批烂”的原始阶段&#xff1f;是时候升级你的“开发模式”了。每个被论文折磨过的人&#xff0c;都默认遵循着同一种“瀑布模型”&#xff1a;花一个月查文献&#xff08;需求分析&#xff09;&#xf…

2026年天津离婚纠纷律所联系电话推荐:精选推荐与使用指南 - 品牌推荐

在2026年的今天,面对婚姻关系的重大变化,寻求专业法律帮助是许多天津市民的明智选择。离婚纠纷不仅涉及复杂的情感纠葛,更关乎财产分割、子女抚养等重大法律权益。在天津这座注重家庭和谐与实质正义的城市,找到一家…

Python无人机机器人健康预警系统

目录Python无人机机器人健康预警系统的摘要项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作Python无人机机器人健康预警系统的摘要 无人机机器人在现代工业、农业、物流和安防等领域发挥着重要作用&#x…

细胞抗衰成分大比拼:NMN、NAD+、NMNH哪一个成分抗衰效果最好? - 速递信息

随着抗衰科学的不断深耕,细胞级抗衰已从高端圈层的隐秘需求,成为全球大众关注的健康热点。在众多抗衰成分中,NAD+、NMN、NMNH因直接关联细胞能量代谢与衰老机制,始终占据话题核心。三者究竟是什么关系?哪一种抗衰…

10个赛博朋克素材网站:科技感视频必备!(2026年更新)

根据《2025年中国视频素材行业发展报告》显示&#xff0c;2025年赛博朋克风格的视频素材下载量同比增长了67%&#xff0c;其中免费素材的需求占比高达82%。这一数据反映出创作者对低成本、高质量赛博朋克素材的迫切需求&#xff0c;尤其是科技感视频领域&#xff0c;赛博朋克元…

2026年史密斯训练器/力量训练器/综合训练器/龙门架训练器厂家竞争格局与顶级厂商深度分析报告 - 2026年企业推荐榜

一、 核心结论 在健身智能化、数据化与空间效率化三大趋势的驱动下,史密斯训练器已从单一的基础力量设备,演变为集安全防护、动作引导、数据反馈及课程交互于一体的智能训练中枢。为精准评估市场主要参与者,本报告构…

社交媒体竖屏视频素材去哪找?2026年10个宝藏网站大盘点

根据《2025年中国社交媒体竖屏视频营销趋势报告》显示&#xff0c;2025年社交媒体平台上竖屏视频的播放量占比已达78%&#xff0c;免费素材使用率同比提升35%。越来越多创作者和品牌开始依赖免费竖屏视频素材提升内容效率&#xff0c;但面对繁杂的素材网站&#xff0c;很多人不…

springboot同城民宿管理与设计系统

目录同城民宿管理与设计系统摘要项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作同城民宿管理与设计系统摘要 随着共享经济的快速发展&#xff0c;民宿行业成为旅游住宿的重要选择。传统民宿管理依赖人工操…

安阳同昌新材料受客户认可吗,全国金属回收企业排名新鲜出炉 - 工业品牌热点

在有色金属冶炼与压延加工领域,专业的真空电炉设备是金属回收再生企业降本增效、合规生产的核心支撑。面对市场上鱼龙混杂的设备供应商,企业如何找到技术可靠、服务完善的合作伙伴?以下结合行业需求,为你推荐5家专…

科普视频动画素材库:2026年10个靠谱网站推荐

根据《2025年中国数字内容创作行业发展报告》显示&#xff0c;2024年科普类视频内容的播放量同比增长超过60%&#xff0c;其中动画素材的使用率提升了45%&#xff0c;越来越多的创作者开始重视动画素材在科普内容中的应用。而选择合适的动画素材库&#xff0c;不仅能节省创作时…

好写作AI|“学术专注力”训练器:你的论文专注度,竟被AI“拿捏”了?

说好写半小时论文&#xff0c;结果刷了2小时短视频&#xff1f;别怪自己&#xff0c;要怪就怪大脑的“默认设置”太落后。是时候给你的专注力来个“系统升级”了。每个与论文搏斗的夜晚&#xff0c;你都可能经历这样的“时间黑洞”&#xff1a;打开文档&#xff0c;郑重写下标题…

SSM springboot的周边转卖交易平台设计 追星商城

目录 SSM与SpringBoot的周边转卖交易平台设计&#xff08;追星商城&#xff09; 项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作 SSM与SpringBoot的周边转卖交易平台设计&#xff08;追星商城&#xff09;…

AI校服识别算法的成本+规划

AI校服识别算法的成本可从开发、部署、运行和维护四个阶段进行系统分析。结合当前&#xff08;截至2026年初&#xff09;公开资料与行业实践&#xff0c;其成本构成如下&#xff1a;一、核心成本构成&#xff08;按模块分类&#xff09;1. 算法研发成本人力成本&#xff1a;计算…

好写作AI|从会议发言到期刊论文:你的PPT,AI能帮你“撑大”成一篇核心吗?

学术会议上侃侃而谈&#xff0c;收获掌声&#xff1b;打开Word准备成文&#xff0c;大脑空空——别慌&#xff0c;你和一篇期刊论文之间&#xff0c;只差一个“内容扩写”的魔法。每一个做过学术报告的研究者&#xff0c;都经历过这种“人格分裂”&#xff1a;在台上&#xff0…

2026高质量3D渲染视频素材下载:10个实用网站推荐

根据《2025年中国数字创意产业发展报告》显示&#xff0c;2025年我国数字创意产业规模突破6万亿元&#xff0c;其中3D渲染视频素材的市场需求同比增长35%。随着短视频、直播、广告等行业的快速发展&#xff0c;创作者对高质量3D渲染素材的需求越来越迫切&#xff0c;但找到合适…

元宇宙平台的房屋租赁管理系统

目录元宇宙平台房屋租赁管理系统摘要项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作元宇宙平台房屋租赁管理系统摘要 元宇宙平台的房屋租赁管理系统是一种基于虚拟现实&#xff08;VR&#xff09;、增强现…

自媒体视觉物料高效创作新路径:稿定设计如何用AI重构内容生产逻辑

在自媒体行业竞争白热化、内容同质化严重的当下&#xff0c;内容传播、商业变现、IP塑造等核心场景对视觉物料的依赖度日益攀升。短视频封面、推文配图、带货海报等物料直接影响流量获取与转化效果&#xff0c;而从业者普遍面临四大痛点&#xff1a;多平台分发需批量产出差异化…

元宇宙平台的整车生产线管理系统的设计与实现

目录元宇宙平台的整车生产线管理系统设计与实现摘要项目技术支持可定制开发之功能亮点源码获取详细视频演示 &#xff1a;文章底部获取博主联系方式&#xff01;同行可合作元宇宙平台的整车生产线管理系统设计与实现摘要 随着工业4.0和数字孪生技术的发展&#xff0c;元宇宙平…

2026 振动台行业优选指南:技术解析与优秀厂家推荐 - 品牌推荐排行榜

随着工业制造高质量、可靠性验证需求日益增长,振动台(Vibration Test Systems)作为力学环境测试的核心设备,已成为航空航天、汽车电子、轨道交通、军工装备等行业的基础试验设施。行业趋势显示,振动试验设备正朝着…

网站收录是什么意思?对SEO优化有什么影响?

网站收录&#xff08;Indexing&#xff09; 是指搜索引擎&#xff08;如 Google、百度等&#xff09;通过其爬虫&#xff08;Crawler&#xff0c;如 Googlebot&#xff09;发现、抓取并将你的网页内容存储到搜索引擎的数据库&#xff08;索引库&#xff09;中的过程。 简单比喻…