C++之智能指针:shared_ptr、unique_ptr、weak_ptr的概念、用法即它们之间的关系

智能指针

(1)概述

A.Why(C++为什么引入智能指针)

C++引入智能指针的根本原因就是解决手动管理动态内存所带来的问题,手动管理动态内存常见的问题如下:内存泄漏、悬挂指针、释放操作未定义等

内存泄漏问题:

当程序用光了它可用的动态内存空间,new就会报错

int *p = new int; //*p的值未定义
int *p2 = new int(); //*p的值初始化为0
//程序用光了它可用的堆内存空间
int *pn = new int; //此时将会抛出异常:std::bad_alloc
int *pn_noThrow = new (nothrow) int; //如果分配失败,将返回空指针nullptr

悬挂指针问题:

当使用delete释放了指向动态内存空间的指针p时,指针p就成为了一个悬挂指针(即在有的机器中,指针p还保存着曾经的内存地址),因此在手动管理动态内存空间的时候,一定要在delete之后将对应指针置为nullptr或0

int *ptr = new int();
delete ptr;
ptr = nullptr; //避免悬挂指针从而引起的未定义定位(不可预知行为)

释放操作未定义问题:

释放一块非new分配的内存或将相同的指针释放多次,其行为是未定义的

B.What(什么是智能指针)

本质是一个封装了原始指针的模板类,在适当的时候(生命周期结束时)自动释放所管理的动态内存

C.Which(有哪些智能指针)

  • shared_ptr
  • weak_ptr
  • unique_ptr
智能指针所有权内存释放
shared_ptr多个 std::shared_ptr 共享所有权通过内部的引用计数机制,当引用计数为 0 时,自动释放内存
weak_ptr不拥有所指向对象的所有权,它只是对 std::shared_ptr 的一种弱引用-
unique_ptr独占所有权当 std::unique_ptr 超出其作用域时,自动释放所管理的内存

(2)How(如何使用智能指针)

C++中的智能指针,其本质都是类模板,因此在学习智能指针的时,我们可以像对待普通类对象一样使用智能指针对象。正是因为它的本质是类对象,因此使用智能指针的一般流程如下:创建智能指针对象和调用智能指针对象的方法

A.智能指针类的成员变量

shared_ptr智能指针:

成员数据说明
T *ptr存放实际数据的动态内存地址
int iCount计数器,用于记录有多少个shared_ptr共享同一块内存空间
deleter删除器,本质是一个函数对象,自定义资源释放的行为

unique_ptr智能指针:

成员数据说明
T *ptr存放实际数据的动态内存地址
deleter删除器,本质是一个函数对象,自定义资源释放的行为

weak_ptr智能指针:

weak_ptr 是一种不控制所指向对象生存期的智能指针,它指向由一个 shared_ptr 管理 的对象。将一个 weak_ptr 绑定到一个 shared_ptr 不会改变 sharedptr 的引用计数。一 旦最后一个指向对象的 shared_ptr 被销毁,对象就会被释放。即使有 weakptr 指向对象, 对象也还是会被释放,因此,weak_ptr 的名字抓住了这种智能指针“弱”共享对象

所以说weak_ptr可以说没有成员数据

B.智能指针类的成员函数

shared_ptr智能指针:

成员函数说明
constexpr shared_ptr() noexcept = default;默认的构造函数
constexpr shared_ptr(nullptr_t) noexcept {}带空指针的构造函数
explicit shared_ptr(T* ptr)传入指向堆内存的一般指针
void swap(shared_ptr& _Other) noexcept交换两个智能指针所管理的内存
void reset() noexcept释放资源
remove_extent_t<_Ty>* get() const noexcept得到所管理动态内存的地址
bool unique() const noexcept是否只有一个引用
long use_count() const noexcept返回shared_ptr对象的引用数

在这里插入图片描述

unique_ptr智能指针:

成员函数说明
constexpr unique_ptr() noexcept默认的构造函数
constexpr unique_ptr(nullptr_t) noexcept带空指针的构造函数
explicit unique_ptr(pointer _Ptr) noexcept传入指向堆内存的一般指针
void swap(shared_ptr& _Right ) noexcept交换两个智能指针所管理的内存
_Dx& get_deleter() noexcept得到删除器对象
pointer release() noexcept释放所管理动态内存的地址
void reset(pointer _Ptr = nullptr) noexcept如果reset函数带有参数,则会释放当前指向的对象,并将unique_ptr指向新的对象

在这里插入图片描述

weak_ptr智能指针:

成员函数说明
constexpr weak_ptr() noexcept = default;默认的构造函数
weak_ptr(const weak_ptr& _Other) noexcept拷贝构造函数
weak_ptr(const shared_ptr<_Ty2>& _Other) noexcept带shared_ptr对象的构造函数
void swap(weak_ptr& _Other) noexcept交换两个智能指针所管理的内存
void reset() noexcept释放资源
bool expired() const noexceptuse_count()为0时返回true
shared_ptr<_Ty> lock() const noexcept转为shared_ptr对象
long use_count() const noexcept返回对应shared_ptr对象的引用数

在这里插入图片描述
在这里插入图片描述

(3)使用智能指针需要注意的事项

  • 不要混合使用常规指针和智能指针

    使用内置指针访问智能指针管理的对象是危险的,无法知道对象何时被销毁

  • 不要使用get()函数初始化另一个智能指针或为另一个智能指针赋值
    在这里插入图片描述

  • 不 deleteget()返回的指针

  • 不使用相同的内存指针初始化(reset)多个智能指针

  • 如果智能指针所管理的内存不是 new 分配的内存,要传递一个删除器


================================================================================
若读者对C++感兴趣,欢迎阅读笔者在学习C++过程中的关于其知识点的总结系列,入口如下:

C++知识点总结全系列文章索引:
【C++知识点总结全系列 (01)】:数据类型、数据类型转换和变量
【C++知识点总结全系列 (02)】:C++中的语句、运算符和表达式详细总结
【C++知识点总结全系列 (03)】:函数(函数参数传递、可变参数、函数返回值等详细介绍)
【C++知识点总结全系列 (04)】:C++类的详细总结与分析
【C++知识点总结全系列 (05)】:IO 类的详细总结和分析
【C++知识点总结全系列 (06)】:STL六大组件总结- 配置器、容器、迭代器、适配器、算法和仿函数
【C++知识点总结全系列 (07)】:模板与泛型编程详细总结与分析
【C++知识点总结全系列 (08)】:面向对象编程OOP


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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

国产开源系统openEuler_24.03_LTS部署安装/基础配置/验证连接实操手册

前言&#xff1a; openEuler 是开放原子开源基金会&#xff08;OpenAtom Foundation&#xff09;孵化及运营的开源项目。 欧拉操作系统(openEuler&#xff0c;简称“欧拉”,“开源欧拉”)是面向数字基础设施的操作系统&#xff0c;支持服务器、云计算、边缘计算、嵌入式等应用场…

ctfshow~菜狗杯 你会数数吗

用010Editor打开文件附件 选择工具->直方图 选择记数&#xff0c;从上到下就是flag ctfshow{a1b2d3e4g56i7j8k9l0}

操作系统内核源码杂谈篇:临界区

临界资源&#xff0c;是指同一时刻只能由一个线程&#xff08;linux下为进程&#xff09;访问的资源&#xff0c;而临界区就是为了确保临界资源访问是单一数据流。 临界区的代码执行&#xff0c;也就是进行原子操作&#xff0c;不会被打断。 先分析RTOS的运行架构&#xff0c…

构建自定义bootos

1 构建自定义bootos BootOS (也称 ramos ),是一个基于内存的操作系统,系统启动后全部加载到内存中运行,不依赖磁盘存储设备,因此可以对硬件层级进行一系列的操作。主要分为两部分内核和文件系统。 1.1 构建vmlinuz内核文件 1.1.1 从现有系统获取 从系统iso镜像获…

3.5、matlab打开显示保存点云文件(.ply/.pcd)以及经典点云模型数据

1、点云数据简介 点云数据是三维空间中由大量二维点坐标组成的数据集合。每个点代表空间中的一个坐标点&#xff0c;可以包含有关该点的颜色、法向量、强度值等额外信息。点云数据可以通过激光扫描、结构光扫描、摄像机捕捉等方式获取&#xff0c;广泛应用于计算机视觉、机器人…

第100+16步 ChatGPT学习:R实现Xgboost分类

基于R 4.2.2版本演示 一、写在前面 有不少大佬问做机器学习分类能不能用R语言&#xff0c;不想学Python咯。 答曰&#xff1a;可&#xff01;用GPT或者Kimi转一下就得了呗。 加上最近也没啥内容写了&#xff0c;就帮各位搬运一下吧。 二、R代码实现Xgboost分类 &#xff08…

【北京迅为】《i.MX8MM嵌入式Linux开发指南》-第二篇 Linux系统编程篇-第三十二章 目录IO

i.MX8MM处理器采用了先进的14LPCFinFET工艺&#xff0c;提供更快的速度和更高的电源效率;四核Cortex-A53&#xff0c;单核Cortex-M4&#xff0c;多达五个内核 &#xff0c;主频高达1.8GHz&#xff0c;2G DDR4内存、8G EMMC存储。千兆工业级以太网、MIPI-DSI、USB HOST、WIFI/BT…

Window 安装Open Cascade

目录 一、下载软件 二、环境配置 一、下载软件 下载网址&#xff1a;Download - Open CASCADE Technology 新手推荐exe方式进行安装&#xff0c;直接就可以使用&#xff0c;这里使用 vc140 &#xff0c;配合vs2015来使用。 假设安装在D盘&#xff0c;安装完成如下&#xff…

栈和队列深入浅出

目录&#xff1a; 一. 栈的概念及使用 二.栈的相关经典OJ 三. 队列的概念及使用 二. 队列的相关经典OJ 一. 栈的概念及使用&#xff1a; 1. 概念&#xff1a; 栈一种特殊的线性表&#xff0c;其只允许在固定的一端进行插入和删除元素操作。进行数据插入和删除操作的一端称为栈…

【前端】ikun-qrcode:极简的二维码生成组件,使用view而非canvas避免层级问题

文章目录 背景ikun-qrcode界面效果如何发布一款自己的插件到uniapp市场。&#xff08;5分钟搞定&#xff09; 背景 之前在uniapp上100行搞定二维码生成&#xff0c; 现在封装为vue组件分享出来&#xff1a; 下载地址&#xff1a; https://ext.dcloud.net.cn/plugin?id19351 …

【C++初阶】C/C++内存管理

【C初阶】C/C内存管理 &#x1f955;个人主页&#xff1a;开敲&#x1f349; &#x1f525;所属专栏&#xff1a;C&#x1f96d; &#x1f33c;文章目录&#x1f33c; 1. C/C内存分布 2. C语言中动态内存管理方式&#xff1a;malloc/calloc/realloc/free 3. C内存管理方式 3…

【Python】AI赋能自动化测试—Applitools Eyes让视觉检查自动化测试更智能、更高效(限时公开)

文章目录 一.视觉回归测试1.什么是视觉回归测试&#xff1f;2.视觉回归测试的必要性3.视觉回归测试是如何工作的&#xff1f;4.常用的视觉回归测试工具有哪些&#xff1f; 二.Applitools Eyes1.是什么2.优缺点3.注册平台账号功能介绍1.界面切换2.单条视觉测试结果解读3.测试视图…

网络开局 与 Underlay网络自动化

由于出口和核心设备 部署在核心机房,地理位置集中,业务复杂,开局通常需要网络工程师进站调测。 因此核心层及核心以上的设备(包含核心层设备,旁挂独立AC设备和出口设备)推荐采用WEB网管开局方式或命令行开局方式。 核心以下的设备(包含汇聚层设备、接入层设备和AP)由于数量众…

发文大刊!Springer旗下1区SCI,收稿量20000+,投稿难度一颗星!

【SciencePub学术】本期&#xff0c;小编给大家推荐的是1本2区计算机综合类SCI&#xff0c;该期刊隶属于Springer出版社&#xff0c;分区逐年上升&#xff0c;现已稳定检索13年&#xff0c;属于Springer旗下的1本口碑优刊。 1 期刊基本信息 【期刊简介】IF&#xff1a;3.0-4.…

【zabbix6监控java-tomcat全流程】

目录 一、监控主机安装zabbix-server1、zabbix的安装2、配置数据库3、为zabbix server配置数据库4、启动服务,web界面安装 二、被监控主机安装tomcat1、安装JDK2、安装tomcat 三、zabbix的服务端安装zabbix-java-gateway四、被监控主机tomcat的配置五、web界面添加主机 一、监控…

python 10的阶乘怎么算

python计算阶乘的方法有很多种&#xff0c;下面给大家介绍三种方法。 第一种&#xff1a;利用functools工具处理 import functools result (lambda k: functools.reduce(int.__mul__, range(1, k 1), 1))(10) print(result) 结果如下&#xff1a; 3628800 第二种&#xff1a…

Tongweb7 日志报错:HttpServletResponse is exceeding the 65535 bytes limit(by lqw)

遇到jsp访问的时候页面加载不全&#xff0c;看tw7日志有如下图信息&#xff1a; 原因&#xff1a; jsp的本质是servlet&#xff0c;编译时会先将他转换成java代码&#xff0c;然后再进行编译。 你的jsp编译成生成的文件太大&#xff0c;导致报错。&#xff08;Java 编译器限制…

【操作系统】定时器(Timer)的实现

这里写目录标题 定时器一、定时器是什么二、标准库中的定时器三、实现定时器 定时器 一、定时器是什么 定时器也是软件开发中的⼀个重要组件.类似于⼀个"闹钟".达到⼀个设定的时间之后,就执行某个指定 好的代码. 定时器是⼀种实际开发中⾮常常用的组件. ⽐如⽹络通…

安全防御---防火墙综合实验3

安全防御—防火墙综合实验3 一、实验拓扑图 二、实验要求 12&#xff0c;对现有网络进行改造升级&#xff0c;将当个防火墙组网改成双机热备的组网形式&#xff0c;做负载分担模式&#xff0c;游客区和DMZ区走FW3&#xff0c;生产区和办公区的流量走FW1 13&#xff0c;办公区…

Jenkins安装nodeJs环境

首先插件市场安装nodeJS插件&#xff0c;我这里已经安装了&#xff0c;没安装的话在 Available plugins 中搜索安装 安装完成后需要下载需要的nodejs版本 新增完成就可以在构建的时候选择当前版本号了