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

news2024/12/24 17:47:21

智能指针

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


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

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

相关文章

React的usestate设置了值后马上打印获取不到最新值

我们在使用usestate有时候设置了值后&#xff0c;我们想要更新一些值&#xff0c;这时候&#xff0c;我们要想要马上获取这个值去做一些处理&#xff0c;发现获取不到&#xff0c;这是为什么呢&#xff1f; 效果如下&#xff1a; 1、原因如下 在React中,当你使用useState钩子…

线程安全(七)ReentrantLock 简介、Condition 条件变量、锁的工作原理、synchronized 与 Lock 的区别

目录 一、ReentrantLock 简介1.1 Reentrant 的特性:1.2 基本语法1.3 ReentrantLock 的主要方法:1.4 lock()、tryLock()、lockInterruptibly() 的区别:二、Condition 条件变量2.1 什么是 Condition 条件变量?2.2 Condition 的核心方法:2.3 Condition 使用示例1:等待与唤醒…

PJA1介导的焦亡抑制是鼻咽癌产生耐药性的驱动因素

引用信息 文 章&#xff1a;PJA1-mediated suppression of pyroptosis as a driver of docetaxel resistance in nasopharyngeal carcinoma. 期 刊&#xff1a;Nature Communications&#xff08;影响因子&#xff1a;14.7&#xff09; 发表时间&#xff1a;2024年6月2…

LLaMA-Factory

文章目录 一、关于 LLaMA-Factory项目特色性能指标 二、如何使用1、安装 LLaMA Factory2、数据准备3、快速开始4、LLaMA Board 可视化微调5、构建 DockerCUDA 用户&#xff1a;昇腾 NPU 用户&#xff1a;不使用 Docker Compose 构建CUDA 用户&#xff1a;昇腾 NPU 用户&#xf…

变阻器与电位器有什么区别?

变阻器和电位器都是可以改变电阻值的电子元件&#xff0c;它们在电路中的作用和调节方式有一定的相似性&#xff0c;但它们之间还是存在一些区别的。 1. 结构上的区别&#xff1a;变阻器主要由固定电阻体和可动滑片组成&#xff0c;通过滑动滑片来改变电阻体的电阻值。而电位器…

数据库(创建数据库和表)

目录 一&#xff1a;创建数据库 二&#xff1a;创建表 2.1&#xff1a;创建employees表 2.2&#xff1a;创建orders表 2.3&#xff1a;创建invoices表 一&#xff1a;创建数据库 mysql> create database mydb6_product; Query OK, 1 row affected (0.01 sec) mysql&g…

linux centos limits.conf 修改错误,无法登陆问题修复 centos7.9

一、问题描述 由于修改/etc/security/limits.conf这个文件中的值不当&#xff0c;重启后会导致其账户无法远程登录&#xff0c;本机登录。 如改成这样《错误示范》&#xff1a; 会出现&#xff1a; 二、解决 现在知道是由于修改limits.conf文件不当造成的&#xff0c;那么就…

智慧农业新纪元:解锁新质生产力,加速产业数字化转型

粮食安全乃国家之根本&#xff0c;“浙江作为农业强省、粮食生产重要省份&#xff0c;在维护国家粮食安全大局中肩负着重大使命。浙江粮食产业经济年总产值已突破4800亿元&#xff0c;稳居全国前列&#xff0c;然而&#xff0c;同样面临着规模大而不强、质量效益有待提升、数字…

JVM高频面试点

文章目录 JVM内存模型程序计数器Java虚拟机栈本地方法栈Java堆方法区运行时常量池 Java对象对象的创建如何为对象分配内存 对象的内存布局对象头实例数据对齐填充 对象的访问定位 垃圾收集器找到垃圾引用计数法可达性分析&#xff08;根搜索法&#xff09; 引用概念的扩充回收方…

字符数组的魅力:C语言字符数组与字符串编程实践

1.概念 字符数组&#xff0c;数组元素是char(字符型)的数组&#xff0c;它可以是一维数组&#xff0c;也可以是二维数组。 2.定义的时候赋值 char ch1[]{c,h,i,n,a}; char ch2[]{"china"}; //相当于 char ch2[] "china"; 元素个数为6&#xff0c;默认会…

探索Linux世界 —— shell与权限的相关知识

一、shell以及其运行原理 1、什么是shell Linux严格意义上说的是一个操作系统&#xff0c;我们称之为“核心&#xff08;kernel&#xff09;“ &#xff0c;但我们一般用户&#xff0c;不能直接使用kernel。而是通过kernel的“外壳”程序&#xff0c;也就是所谓的shell&#x…

6个高效再利用的UI作品集设计模板

UI 作品集是指用户界面设计师的个人作品集。它展示了设计师的设计能力、技巧和风格&#xff0c;也是充分展示他们设计能力的证明。优秀的UI 作品集应具有简洁明了、美观大方、良好的互动体验和明确的目标。本文将从两个方面的介绍 Ui 作品集模板的全部内容&#xff1a;UI 作品集…

Linux - 基础开发工具(yum、vim、gcc、g++、make/Makefile、git、gdb)

目录 Linux软件包管理器 - yum Linux下安装软件的方式 认识yum 查找软件包 安装软件 如何实现本地机器和云服务器之间的文件互传 卸载软件 Linux编辑器 - vim vim的基本概念 vim下各模式的切换 vim命令模式各命令汇总 vim底行模式各命令汇总 vim的简单配置 Linux编译器 - gc…

近距离无线通信技术简介

个人早几年整理的材料&#xff0c;学识有限&#xff0c;喜欢指正。

Java.Net.UnknownHostException:揭开网络迷雾,解锁异常处理秘籍

在Java编程的浩瀚宇宙中&#xff0c;java.net.UnknownHostException犹如一朵不时飘过的乌云&#xff0c;让开发者在追求网络畅通无阻的道路上遭遇小挫。但别担心&#xff0c;今天我们就来一场说走就走的探险&#xff0c;揭秘这个异常的真面目&#xff0c;并手把手教你几招应对之…

【React】React18 Hooks 之memo、useCallback

目录 React.memo()案例1: 无依赖项&#xff0c;无props案例1: props比较机机制&#xff08;1&#xff09;传递基本类型&#xff0c;props变化时组件重新渲染&#xff08;2&#xff09;传递的是引用类型的prop&#xff0c;比较的是新值和旧值的引用&#xff08;3&#xff09;保证…

pyinstall 打包基于PyQt5和PaddleOCR的项目为.exe

简介&#xff1a; 最近做了一个小项目&#xff0c;是基于PyQt5和PaddleOCR的。需要将其打包为.exe&#xff0c;然后打包过程中遇到了很多问题&#xff0c;也看了很多教程&#xff0c;方法千奇百怪的&#xff0c;最后也是一步一步给试出来了。记录一下&#xff0c;防止以后忘记…

【2024年“数据要素×”大赛宁夏分赛】赛程制度

“数据要素”大赛宁夏分赛怎么报名&#xff1f;看这里 官方网站&#xff1a;https://nxsjysds.sznxgs.com/ 赛程制度 &#xff08;一&#xff09;启动报名&#xff08;7月16日-8月10日&#xff09;举办启动仪式&#xff0c;组织线上和线下推广工作&#xff0c;动员参赛队伍报…

vue3 vxe-grid修改currentPage,查询数据的时候,从第一页开始查询

1、当我们设置好VxeGrid.Options进行数据查询的时候,下面是可能的设置&#xff1a; const gridOptions reactive<BasicTableProps>({id: UserTable,showHeaderOverflow: false,showOverflow: true,keepSource: true,columns: userColumns,size: small,pagerConfig: {cur…

Python求均值,方差,标准差

参考链接&#xff1a;变异系数&#xff08;Coefficient of Variation,COV&#xff09;和协方差&#xff08;Covariance, Cov&#xff09;-CSDN博客 参考链接&#xff1a;pandas中std和numpy的np.std区别_numpy pandas std-CSDN博客 在计算蛋白质谱数据中的每个蛋白对应的变异…