当前位置: 首页 > news >正文

智能指针原理、使用和实现——C++11新特性

一、智能指针的理解

问题:什么是智能指针?为什么要有智能指针?智能指针解决什么样的问题?

要明白上面这些问题,我们先引入一个程序。

代码语言:javascript

AI代码解释

double div(double x, double y) { int* p = new int(120); if (y == 0) { string s = "y can not be zero."; throw s; } delete p; return x / y; } int main() { try { double x = 2, y = 0; div(x, y); } catch (string s) { cout << s << endl; } return 0; }

上面这段程序,如果出现抛异常的话,p的内存是没有办法释放的。

智能指针简称RAll,是一种自动化管理资源的类模板,这里指的资源可以是:动态开辟的内存,文件指针,网络连接,互斥锁等等。RAII在获取资源时把资源委托给⼀个对象,接着控制对资源的访问,利用对象的⽣命周期结束时会自动析构的特性来完成对资源的自动释放,这样保障了资源的正常释放,避免资源泄漏问题。

二、智能指针的类型

智能指针其实就是在原指针的基础上套一个类,如果就这样简单的想会有一个非常致命问题——当一块空间被两个智能指针对象指向时会析构两次,从而引发编译器报错

库中的智能指针有很多,用法都一样,区别在于处理同一块空间会被释放两次的方法不同。接下来我们就来看这些智能指针是如何处理的。

  • auto_ptr:在做拷贝构造和赋值重载时,把原对象的资源管理权直接转移给新的对象,原对象指向空,保证一块资源只被一个智能指针管理,从而达到一块资源只被释放一次的目的。但是这种做法会使原指针悬空,如果被误用会导致访问报错的问题。推荐指数:⭐
  • unique_ptr:不允许做拷贝构造和赋值重载操作,从而达到一块资源只被释放一次的目的。如果用不到这两个函数的话可以考虑用这个智能指针。推荐指数:⭐⭐⭐⭐
  • shared_ptr:支持多个对象指向同一块资源,它底层用的是引用计数的方法,这是一个很优秀的智能指针,在下文我们会重点来学习该指针的具体原理和实现。推荐指数:⭐⭐⭐⭐⭐

三、智能指针的使用

这里就以shared_ptr为例,其他都是一样的,首先shared_ptr本质就是一个类模板,需要我们传入模板参数,比如我们需要让它管理一个int类型的指针。那么它的类型就是:

shared_ptr<int>

然后只需要我们创建变量和传入手动申请的空间进行构造。如:

shared_ptr<int> p(new int);

四、shared_ptr的原理

1.引用计数

原理:使用一个变量记录有几个对象在管理该资源,从而决定是否释放该资源。例如:当一个对象走到析构函数时也就是该对象生命结束了不再管理这块资源了,所以引用计数减一,此时如果引用计数变成0的话说明该资源没有对象管理了,可以直接释放,如果不是0,说明还有对象在管理,所以不用处理。

2.循环引用问题

例如这样一个环形链表,当n1生命周期结束时发现,还有对象(n2的_next)在指向它,所以没有释放资源,当n2生命周期结束时发现还有对象(n1的_next)指向它,所以也没有释放资源。

也可以这样想:n1的资源什么时候释放,因为n2还在用呢,需要n2的资源释放掉,那么n2的资源什么时候释放,因为n1还在用呢,需要n1的资源释放掉。循环往复始终释放不了,所以导致内存泄漏。

3.weak_ptr处理逻辑

shared_ptr虽然很优秀,但依旧有缺陷——循环引用问题,所以就有了weak_ptr用来辅助shared_ptr来解决这个问题。

weak_ptr不⽀持RAII,也不⽀持访问资源,所以我们看⽂档发现weak_ptr构造时不⽀持绑定到资源,只⽀持绑定shared_ptr,绑定到shared_ptr时,不增加shared_ptr的引⽤计数,那么就可以解决上述的循环引⽤问题。weak_ptr没有重载operator*和operator->等,因为他不参与资源管理,那么如果他绑定的shared_ptr已经释放了资源,那么他去访问资源就是很危险的。weak_ptr⽀持expired检查指向的资源是否过期,use_count也可获取shared_ptr的引⽤计数,weak_ptr想访问资源时,可以调⽤lock返回⼀个管理资源的shared_ptr,如果资源已经被释放,返回的shared_ptr是⼀个空对象,如果资源没有释放,则通过返回的shared_ptr访问资源是安全的。

http://www.jsqmd.com/news/476567/

相关文章:

  • 计算机毕业设计springboot数字化心理健康服务系统的设计与实现 基于SpringBoot的“树洞“心理咨询服务平台的设计与实现 基于SpringBoot的在线心理支持与智慧辅导平台
  • OpenClaw 生态全景:九大类 Open Claw 产品深度横评
  • 收藏!彻底解决RAG系统效果不佳问题:这套组合策略让准确率飙升60%
  • 从岭回归到循环矩阵:KCF算法核心数学工具全解析
  • 改进蚁群算法agv路径规划。 基于matlab的二维栅格地图的精英蚁群算法的路径规划算法仿真
  • 第10章 数据库的安全与保护
  • 基于MATLAB的准Z源NpC三电平逆变器:创新SVPWM调制与中性点平衡算法的研究与实践
  • 智能体记忆详解:解锁大模型长时推理与持续学习能力
  • 权威指南 第三章
  • pipx — 安全便捷地管理 Python 命令行工具
  • 从施密特触发器到迟滞比较器:运算放大器正反馈应用的深度解析
  • 网站打不开(空白页/404/500)问题|已解决
  • 带隙基准技术的Cadence电路设计:超低漂、高电源抑制比、精细化温度补偿及功耗优化详解(附带...
  • C++:继承】面向对象编程精要:C++继承机制深度解析与最佳实践
  • STM32C8T6+WS2811 RGB彩灯时序调试实战与PWM控制对比
  • 为什么要做信创产品评估测试?对企业有哪些核心好处?
  • 一文读懂AI智能体(Agent):小白也能掌握的大模型应用新方向
  • 网站进入后台后,提示“后台 JavaScript 加载失败”,部分功能(如编辑文章、切换菜单)无法使用问题|已解决
  • 2026年真空袋厂家电话查询推荐:高效对接与使用贴士 - 十大品牌推荐
  • Cadence Bandgap电路设计实战:从稳定性、噪声到PSRR的仿真优化全解析
  • 基于改进鹈鹕算法(IPOA)优化BP神经网络的时间序列预测(IPOA-BP) 鹈鹕算法是202...
  • C++:继承和多态】多态加餐:面试常考——多态的常见问题11问
  • 2026河北木纹水泥板厂商综合实力与选型指南 - 2026年企业推荐榜
  • Leather Dress Collection LoRA集合详解:各模型训练数据分布与风格边界说明
  • BMS软件架构实战 — 继电器驱动与状态诊断策略
  • AgenticRAGTracer:首个LLM自动构建的Agentic RAG多跳推理诊断工具,小白也能轻松学习大模型评估方法
  • Multisim实战:从零构建MC1496振幅调制器(附仿真、PCB与调试全记录)
  • 2026年选购指南:胶粘石胶水直销厂家综合实力解析 - 2026年企业推荐榜
  • 深入解析大语言模型智能体:核心架构与多智能体协作框架,值得收藏的深度指南
  • 【DVWA实战】File Upload High级别攻防:绕过三重校验与哥斯拉图片马实战