【C++入门到精通】智能指针 shared,C++入门到精通智能指针shared详解

马肤

温馨提示:这篇文章已超过470天没有更新,请注意相关的内容是否还可用!

摘要:本教程将带你从入门到精通掌握C++中的智能指针,特别是shared_ptr。我们将详细介绍shared_ptr的基本概念、优势和使用方法,包括其内存管理、生命周期和线程安全特性。通过学习本教程,你将深入了解shared_ptr如何帮助管理动态分配的内存,避免内存泄漏和野指针等问题,提高代码质量和可靠性。适合对C++感兴趣的初学者和进阶开发者。

【C++入门到精通】智能指针 shared,C++入门到精通智能指针shared详解 第1张

欢迎阅读本系列文章的第二篇,我们将深入探讨与std::shared_ptr相关的主题,在上一篇文章中,我们了解了std::shared_ptr的强大功能,同时也提到了它可能面临的一个主要问题——循环引用,当两个或多个对象相互持有对方的shared_ptr引用时,就会形成循环引用,导致这些对象无法被正确释放,从而造成内存泄漏。

为了解决这个问题,C++引入了另一个智能指针类——std::weak_ptrstd::weak_ptrstd::shared_ptr的伙伴,它可以观察并引用由shared_ptr管理的对象,但不会增加对象的引用计数,从而避免了循环引用导致的内存泄漏问题。

一、std::shared_ptr的循环引用

1. 概念

循环引用是指两个或多个对象彼此持有对方的shared_ptr引用,形成一个环状的依赖关系,这种情况下,即使没有其他外部引用指向这些对象,它们的引用计数也无法归零,导致内存泄漏,因为对象的引用计数永远无法降到零,所以它们的析构函数不会被调用,资源无法正确释放。

2. 示例分析

我们来看一个存在循环引用的代码示例:

struct ListNode {
    int _data;
    shared_ptr<ListNode> _prev;
    shared_ptr<ListNode> _next;
    // ... 其他成员和函数 ...
};

在这个例子中,每个ListNode都持有一个指向前后节点的shared_ptr,这就形成了一个循环引用,因为前一个节点持有对后一个节点的引用,后一个节点又持有对前一个节点的引用,如果没有外部力量来打破这个循环,这些节点将永远不会被释放。

二、std::weak_ptr的简介和使用

1. 简介

std::weak_ptr是一个智能指针类,它可以观察并引用由shared_ptr管理的对象,但不会增加对象的引用计数,这意味着即使存在对对象的weak_ptr引用,对象仍然可以在没有其他shared_ptr引用时正常被释放。

2. weak_ptr模板类提供的成员方法

weak_ptr(): 构造函数,用于创建一个空的weak_ptr。

weak_ptr(const shared_ptr&): 接受一个shared_ptr作为参数,创建一个对相同对象的weak_ptr。

operator shared_ptr(): 将weak_ptr转换为shared_ptr,如果对象仍然存在(即未被释放),则返回一个有效的shared_ptr;否则返回一个空的shared_ptr。

lock(): 尝试将weak_ptr转换为shared_ptr,如果对象仍然存在并且可以被安全地引用,则返回一个有效的shared_ptr;否则返回一个空的shared_ptr或抛出异常。

expired(): 检查所引用的对象是否已被删除,如果对象已被删除,返回true;否则返回false。

use_count(): 返回共享对象的shared_ptr引用数量(不包括weak_ptr)。

3. 使用示例

为了解决上面提到的循环引用问题,我们可以使用weak_ptr来打破循环:

struct ListNode {
    int _data;
    weak_ptr<ListNode> _prev; // 使用weak_ptr代替shared_ptr
    shared_ptr<ListNode> _next; // 对下一个节点的shared_ptr引用仍然保留
    // ... 其他成员和函数 ...
};

通过使用weak_ptr来持有上一个节点的引用,我们打破了循环引用,即使两个节点相互持有对方的引用,当没有其他外部引用时,它们仍然可以被正确释放。

C++模拟实现和温馨提示

关于std::weak_ptr的C++模拟实现细节较为复杂,涉及到内部引用计数和锁机制等,在此不展开详细描述,温馨提示:在使用std::weak_ptr时,确保在适当的时候使用lock()方法将其转换为shared_ptr,以避免悬空指针和未定义行为,注意管理weak_ptr的生命周期,确保在不再需要观察对象时及时销毁weak_ptr,这样可以避免潜在的内存泄漏和错误。


0
收藏0
文章版权声明:除非注明,否则均为VPS857原创文章,转载或复制请以超链接形式并注明出处。

相关阅读

  • 【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法,Matlab/Simulink自动生成代码的五种选择结构实现方法(二),Matlab/Simulink自动生成代码的五种选择结构实现方法详解(二)
  • 超级好用的C++实用库之跨平台实用方法,跨平台实用方法的C++实用库超好用指南,C++跨平台实用库使用指南,超好用实用方法集合,C++跨平台实用库超好用指南,方法与技巧集合
  • 【动态规划】斐波那契数列模型(C++),斐波那契数列模型(C++实现与动态规划解析),斐波那契数列模型解析与C++实现(动态规划)
  • 【C++】,string类底层的模拟实现,C++中string类的模拟底层实现探究
  • uniapp 小程序实现微信授权登录(前端和后端),Uniapp小程序实现微信授权登录全流程(前端后端全攻略),Uniapp小程序微信授权登录全流程攻略,前端后端全指南
  • Vue脚手架的安装(保姆级教程),Vue脚手架保姆级安装教程,Vue脚手架保姆级安装指南,Vue脚手架保姆级安装指南,从零开始教你如何安装Vue脚手架
  • 如何在树莓派 Raspberry Pi中本地部署一个web站点并实现无公网IP远程访问,树莓派上本地部署Web站点及无公网IP远程访问指南,树莓派部署Web站点及无公网IP远程访问指南,本地部署与远程访问实践,树莓派部署Web站点及无公网IP远程访问实践指南,树莓派部署Web站点及无公网IP远程访问实践指南,本地部署与远程访问详解,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南,树莓派部署Web站点及无公网IP远程访问实践详解,本地部署与远程访问指南。
  • vue2技术栈实现AI问答机器人功能(流式与非流式两种接口方法),Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法探究,Vue2技术栈实现AI问答机器人功能,流式与非流式接口方法详解
  • 发表评论

    快捷回复:表情:
    评论列表 (暂无评论,0人围观)

    还没有评论,来说两句吧...

    目录[+]

    取消
    微信二维码
    微信二维码
    支付宝二维码