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;
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

在Spring Cloud使用Hystrix核心组件,并注册到Eureka注册中心去

其实吧&#xff0c;写Spring Cloud系列&#xff0c;我有时候觉得也挺难受的&#xff0c;因为Spring Cloud的微服务启动都需要一个一个来&#xff0c;并且在IDea中也需要占用比较大的内存&#xff0c;并且我本来可以一篇写完5大核心组件的&#xff0c;但是我却分了三篇&#xff…

QT 重定向qdebug输出到自绘界面

因为在嵌入式中调试qt需要查看输出信息,特意写了一个类用户便捷查看qdebug信息 界面如下: 提供了开始,停止,保存,清空,退出功能,具体代码下文给出 文件如下 #ifndef QDEBUGREDIRECT_H #define QDEBUGREDIRECT_H /**qdebug 重定向类 定向到界面控件*李吉磊 2023.12.7* */#in…

【dig命令查询方法】

dig&#xff08;Domain Information Groper&#xff09;是一个用于查询DNS&#xff08;域名系统&#xff09;的命令行工具&#xff0c;它可以帮助您获取关于域名的各种信息&#xff0c;如IP地址、MX记录、NS记录等。下面是dig的详细使用教程。 基本语法&#xff1a; dig [ser…

【数据库】树形数据组织架构下的封锁并发控制,B树索引并发访问控制,树协议原理及案例分析

数据库并发访问树协议 ​专栏内容&#xff1a; 手写数据库toadb 本专栏主要介绍如何从零开发&#xff0c;开发的步骤&#xff0c;以及开发过程中的涉及的原理&#xff0c;遇到的问题等&#xff0c;让大家能跟上并且可以一起开发&#xff0c;让每个需要的人成为参与者。 本专栏会…

docker基本管理和概念

1、定义&#xff1a;一个开源的应用容器引擎&#xff0c;基于go语言开发&#xff0c;运行在liunx系统中的开源的、轻量级的“虚拟机” docker的容器技术可以在一台主机上轻松的为任何应用创建一个轻量级的、可移植的、自给自足的容器 docker的宿主机是liunx系统&#xff0c;集…

深度学习与逻辑回归模型的融合--TensorFlow多元分类的高级应用

手写数字识别 文章目录 手写数字识别1、线性回归VS逻辑回归Sigmoid函数 2、逻辑回归的基本模型-神经网络模型3、多元分类基本模型4、TensorFlow实战解决手写数字识别问题准备数据集数据集划分 特征数据归一化归一化方法归一化场景 标签数据独热编码One-Hot编码构建模型损失函数…

NLP自然语言处理学习笔记

参考&#xff1a;NLP&#xff08;自然语言处理&#xff09;介绍 - 知乎 (zhihu.com) 一、NLP是什么 自然语言处理( Natural Language Processing, NLP)是计算机科学领域与人工智能领域中的一个重要方向。它研究能实现人与计算机之间用自然语言进行有效通信的各种理论和方法。自…

uni-app 微信小程序之好看的ui登录页面(一)

文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面&#xff08;一&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;二&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;三&#xff09; uni-app 微信小程…

原生微信小程序将字符串生成二维码图片

weapp-qrcode.js再最后 inde.ts中的内容 // pages/qrCode/index.ts // 引入weapp-qrcode.js文件 var QRCode require(../../utils/weapp-qrcode) Page({/*** 页面的初始数据*/data: {orderNo:"",imagePath:},/*** 生命周期函数--监听页面加载*/onLoad(options:any)…

渗透测试(Lab1.0)

1、用搜索引擎Google或百度搜索麻省理工学院网站中文件名包含“network security”的pdf文档&#xff0c;截图搜索得到的页面。 2、照片中的女生在哪里旅行&#xff1f; 截图搜索到的地址信息。 搜索餐厅的名字&#xff0c;找一下关键词 3、手机位置定位 通过LAC&#xff0…

【AIGC】prompt工程从入门到精通--图片生成专题

本文为系列教程【AIGC】prompt工程从入门到精通的子教程。 一、介绍 与文本提示相比&#xff0c;找到最佳的提示词来生成完美的图片并没有那么成熟。这可能是因为创建对象自身的挑战&#xff0c;这些对象基本上是主观的并且往往缺乏良好的准确性度量方法。 本指南涵盖了基本…

前端典例算法集合

前言 刷算法顺序&#xff1a;1、熟悉本文章第1点的内容&#xff1b;2、刷力扣算法&#xff0c;可以参考这本书的顺序与思想&#xff1a;代码随想录完整版PDF下载 | 合集下载 | 百度云 | | 代码随想录 (programmercarl.com) 3、刷牛客的高频考题 1、熟悉数组Array&#xff0c…

uni-app 微信小程序之好看的ui登录页面(四)

文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面&#xff08;一&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;二&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;三&#xff09; uni-app 微信小程…

uni-app 微信小程序之好看的ui登录页面(二)

文章目录 1. 页面效果2. 页面样式代码 更多登录ui页面 uni-app 微信小程序之好看的ui登录页面&#xff08;一&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;二&#xff09; uni-app 微信小程序之好看的ui登录页面&#xff08;三&#xff09; uni-app 微信小程…

2023五岳杯量子计算挑战赛数学建模思路+代码+模型+论文

目录 计算力网络&#xff08;CPN&#xff09;是一种新型的信息基础设施&#xff0c;完整论文代码见文末 问题描述 2.1 问题1 2.2 问题2 2.3 问题3 问题1的解答过程&#xff1a; 问题3的解答过程&#xff1a; 决策优化应用场景&#xff1a;人工智能模型超参数调优 背景信…

【开源】基于Vue和SpringBoot的车险自助理赔系统

项目编号&#xff1a; S 018 &#xff0c;文末获取源码。 \color{red}{项目编号&#xff1a;S018&#xff0c;文末获取源码。} 项目编号&#xff1a;S018&#xff0c;文末获取源码。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 角色管理模块2.3 车…

MQTT源码分析

目录 MQTT源码分析 1. MQTT客户端功能 2. 客户端软件如何实现 3. 程序分层 4. 情景分析 4.1 连接服务器 4.2 创建线程 4.3 发布消息 4.4 最复杂&#xff1a;订阅消息 MQTT源码分析 分析源码&#xff1a;mqttclient\test\emqx\test.c 参考资料&#xff1a; kawaii-mqt…

【开源】基于Vue.js的二手车交易系统

文末获取源码&#xff0c;项目编号&#xff1a; S 084 。 \color{red}{文末获取源码&#xff0c;项目编号&#xff1a;S084。} 文末获取源码&#xff0c;项目编号&#xff1a;S084。 目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 二手车档案管理模块…

RabbitMQ 常见面试题

目录 1.前置知识1.1.什么是 MQ&#xff1f;它有什么作用&#xff1f;1.2.什么是消费者生产者模型&#xff1f;1.3.AMQP 是什么&#xff1f; 2.RabbitMQ 入门2.1.什么是 RabbitMQ&#xff1f;有什么特点&#xff1f;2.2.RabbitMQ 的核心概念有哪些&#xff1f;2.2.1.生产者 (Pro…

720度vr虚拟家居展厅提升客户的参观兴致

VR虚拟展厅线上3D交互展示的优势有以下几点&#xff1a; 打破了场馆的展示限制&#xff0c;可展示危险性制品、珍贵稀有物品、超大型设备等&#xff0c;同时提供了更大的展示空间和更丰富的展示内容。 可提供企业真实环境的实时VR全景参观&#xff0c;提升潜在客户信任度。 提供…