P30 C++智能指针

前言

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《C++_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3: ​​​​​​《 链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介  :  这章我们将学习一下C++的智能指针

仔细算了一下,好像也好多天没有更新C++系列了,因为最近在嵌入式的项目,然后老出Bug,就很烦,就来学点C++来散下心

大概就是操作界面加摄像头做识别,加网络控制,还有温湿度曲线图,这是还没搞好,搞好了在考虑做个专栏了 

我们回归主题,这章我们学C++的智能指针,学习智能指针之前,我们先要了解一下什么是指针

本期的主题是 C++ 中的智能指针。

P7 C++指针-CSDN博客

在这里,我们将讨论什么是智能指针以及它能为你做什么。

在之前的内容中,我们讨论了 new、delete 这些内容。

new 是在堆上分配内存,需要 delete 来释放内存,

因为它不会自动的释放内存。

智能指针是实现这一过程自动化的一种方式。

当使用智能指针时,你可以不用调用 delete,

在很多情况下,甚至不需要调用 new。

很多人都倾向于使用不调用 new 或 delete 的这种 C++ 编程风格,

智能指针是实现这个的一种方法。

01 unique_ptr作用域指针

智能指针本质上是一个原始指针的包装,

当你创建一个智能指针,它会调用 new 并为你分配内存,然后基于你使用的智能指针,这些内存会在某一时刻自动释放。

让我们来看看第一个,也是最简单的智能指针 unique_ptr。

unique_ptr 是作用域指针,超出作用域时,它会被销毁。

当你想要一个作用域内使用的指针的时候,

unique_ptr 是很的参考。

让我们来看一个例子。

使用智能指针的第一步要先包含 memory 头文件。

现在我们有了 Entity 类,它有构造函数和析构函数

会在调用时打印相应的信息

这样我们就能了解这些智能指针的行为。

1.1 unique_pt实例化对象

在主函数中,我们在一个空作用域下使用 unique_ptr 来分配一个 Entity。

使用的方法就是如上所示。

这里有个需要注意的点就是, unique_ptr 的构造函数是 explicit 的

没有隐式转换功能, 需要显式的调用构造函数,

这就是使用 unique_ptr 的一种方式,

所以你不能这样写 std::unique_ptr entity()= new Entity()。

然后你就可以像普通的指针一样使用 entity 了。

还有一种方法就是

当然更好的方法是先使用 std::make_unique,再赋值给 unique_ptr。

    std::unique_ptr<Entity>entity2 = std::make_unique<Entity>();

这对于 unique_ptr 很重要,主要原因是出于异常安全

因为如果构造函数碰巧抛出异常,它会稍微安全一点

你不会得到一个没有引用的悬空指针,从而造成内存泄漏

这个之后的系列会介绍。

上面的程序调试后就会有这样的效果,申请的这段内存在作用域结束的时候被释放了。

这就是最简单的智能指针了,非常有用,开销很低,它甚至没有开销,

它只是一个栈分配对象,当栈分配对象死亡时,它将调用 delete,释放内存。

1.2 unique_ptr智能指针的小细节

现在出现一个问题,正如上面提到的,如果你想复制这个指针,

使得这个指针可以被传递到一个函数或者另一个类中,然而你却不能复制它。

02 shared_ptr共享指针

如果你真有这样的需求,那么可以使用共享指针 shared_ptr

shared_ptr 有点不同,它还在底层做了很多其它的事情

shared_ptr 实现的方式实际上取决于编译器和你在编译器中使用的标准库

目前来看,它使用的主要是引用计数

引用计数基本上是一种方法,可以跟踪你的指针有多少个引用,

一旦引用计数达到零,它就被删除了。

举个例子,我创建了一个共享指针 shared_ptr,然后创建了另一个 shared_ptr 来复制它,我的引用计数是2(第一个和第二个,共两个),当第一个挂掉的时候,引用计数器就会减少1。当最后一个挂掉的时候,引用计数回到零,内存被释放。

使用共享指针 shared_ptr的方法很简单,如下举例。

shared_ptr 有点不一样的地方在于,它需要分配另一块内存,叫做控制块,

用来存储引用计数,所以如果你首先创建一个 new Entity,

然后将其传递给 shared_ptr 构造函数,它必须分配,

做2次内存分配(先做一次 new Entity 的分配,然后是 shared_ptr 控制内存块的分配)。

如果你用 make_shared,你能把它们组合起来,这样更有效率。

你不妨按照下面的例子做一个简单的测试,提前想一下调试过程,运行看看是否和你想得一样。

可以看到构造函数已经被创建了

因为构造函数里面的cout已经被打印了

然后当计数为0的时候,它将调用 delete,释放内存

这些都是非常好的工具,你可以经常使用它们,它们可以让你的代码自动化,防止你因为忘记调用 delete 而造成内存泄漏。

shared_ptr 是有一点额外的开销的,因为它的引用计数系统。但是话又说回来,很多倾向于编写自己的内存管理系统的人,也一样会有一些开销。

如果决定了要使用智能指针,建议你优先使用 unique_ptr,然后是 shared_ptr,这才是正确的方式。

测试代码

#include <iostream>
#include <memory>class Entity
{
private:public:Entity(){std::cout<<"Entity Created"<<std::endl;}~Entity(){std::cout<<"Entity Destroyed"<<std::endl;}
};int main()
{{std::shared_ptr<Entity> entity;{std::shared_ptr<Entity> shared_Entity = std::make_unique<Entity>();entity = shared_Entity;}
}return 0;
}

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

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

相关文章

全屏显示除了快捷键F11之外,还可以其他替代方法,毕竟F11不是万能的

本文介绍了如何在Windows11上实现全屏显示。根据上下文的不同&#xff0c;有些方法比其他方法更好。 使用Windows 11全屏键盘快捷方式 如果你计划经常使用全屏&#xff0c;只记住一个Windows键盘快捷键很可能会让你达到目的&#xff1a;F11。你会在键盘的最上面一排找到那个键…

SCADA软件工具有多少免费的?

随着工业自动化的飞速发展&#xff0c;SCADA系统已经成为工业领域智能化转型绕不开的重要工具&#xff0c;不少个人和公司也都加入到了学习研究SCADA系统的队伍中。数维图小编耗费大量时间整理了国内外免费&#xff08;非完全免费&#xff09;的SCADA软件工具&#xff0c;有部分…

局域网共享打印机设置,解决709、11B等一切共享问题

Win7、Win10、Win11添加共享打印机经常出现局域网共享打印机出错&#xff0c;常规的添加方式是SMB共享&#xff0c;一更新就出问题&#xff0c;报错0x00000709、0x0000011b等。 网上有许多方法&#xff0c;如卸载更新补丁&#xff0c;替换“win32spl.dll”文件&#xff0c;修改…

GEE:构建和调用自己的 js 函数库

作者&#xff1a;CSDN _养乐多_ 本文记录了在Google Earth Engine&#xff08;GEE&#xff09;上构建自己的 js 函数库的步骤。构建自己的函数库以方便代码调用和扩展。 文章目录 一、创建lib文件二、调用lib库三、附加3.1 定义函数3.2 js 库中函数互相调用 一、创建lib文件 …

文字处理工具Word mac软件特点

Microsoft Word mac是一款文字处理软件。它是 Microsoft office 套件的一部分&#xff0c;已广泛用于创建、编辑和格式化文本文档。 Word mac软件特点 改进的协作工具&#xff1a;使用 Microsoft Word 2021&#xff0c;多个用户可以同时处理一个文档&#xff0c;从而更轻松地与…

二叉树的层平均值[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10-5 以内的答案可以被接受。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;[3.00000,14.50000,1…

堆栈,BSS,DATA,TEXT

一、目标文件 首先目标文件的构成&#xff0c;Linux下就是.o 文件 编译器编译源码后生成的文件叫目标文件&#xff08;Object File&#xff09;。 目标文件和可执行文件一般采用同一种格式&#xff0c;这种存储格式为 ELF。 目前文件的内容至少有编译后的机器指令代码和数据&a…

汽车软件大时代,如何提升软件工程创新力?

当前&#xff0c;传统汽车产业正加速数字化转型&#xff0c;“软件定义汽车”不断深化。在电动化、智能化和网联化趋势下&#xff0c;汽车软件已经成为汽车技术革新和发展的核心驱动力之一。根据亿欧智库发布的《2023中国智能电动汽车车载软件市场分析报告》&#xff0c;2022年…

产品成本收集器流程演示

感谢大佬的文章&#xff0c;我只是一个翻译搬运工&#xff0c;原文地址&#xff1a;产品成本收集器 概述 SAP 令人兴奋的部分之一是它在不同操作模块之间的集成程度。使用产品成本收集器来跟踪生产就是一个很好的例子。在本博客中&#xff0c;我计划遵循产品成本收集器流程&a…

Matlab 点云对称性检测

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 这是一个很有趣的功能,它的思路其实与ICP算法的思路有些相似: 首先,它会初始化两个旋转角度,即绕x轴旋转与绕y轴旋转,初始的过程是将点对称(镜像)过去,计算与匹配点之间的距离误差,误差最小者为最优初始值…

C语言之Switch语句

目录 Switch语句和break语句 复杂的Switch语句 选择语句 if语句会根据某个条件的判断结果&#xff0c;将程序的流程分为两支&#xff0c;而Switch语句&#xff0c;则会将程序分为多个分支。 Switch语句和break语句 让我们来看下Switch语句的结构图&#xff1a;&#xff08…