当前位置: 首页 > news >正文

C++学习笔记----6、内存管理(五)---- 智能指针(2)

        书接上回!

        make_unique()使用值初始化。例如,将初始类型初始化为0,对象为缺省构造。如果不需要这样的值初始化,例如,因为不管怎么样你都会覆写共初始值,你就可以省略值初始化,通过使用make_unique_for_overwrite()函数提高性能,该函数会使用缺省初始化值。对于初始类型,这意味着它们不会被初始化,会在内存中包含任何可能的值,而对象仍会是初始构造时的值。

        你也可以通过直接调用其构造函数来生成unique_ptr。注意Simple一定要用两次:

unique_ptr<Simple> mySimpleSmartPtr { new Simple{} };

        我们以前讨论过,模板值预测(CTAD)通常可以用于让编译器预测出模板类型的值,基于传递给类模板的构造函数的参数。例如,允许写出vector v{1,2}而不用vector<int> v{1,2}.CTAD对于unique_ptr不好使,所以不能省略模板类型参数。

        在c++17之前,只能使用make_unique()不仅仅是因为它意味着只能指定一次类型,还因为安全的原因!考虑以下对foo()函数的调用:

foo(unique_ptr<Simple> { new Simple{} }, unique_ptr<Bar> { new Bar { data() } });

        如果Simple或者Bar的构造函数或者data()函数抛出了一个例外,它依赖于你的编译器的优化,Simple或者Bar对象是可能会有内存渗露的。而对于make_unique()则不会有内存渗露:

foo(make_unique<Simple>(), make_unique<Bar>(data()))

        从c++17开始,对foo()的调用都是安全的,但是建议使用make_unique(),因为它易于阅读。

总是要用make_unique()来生成unique_ptr。

1.2、使用unique_ptr

        标准智能指针的一个最大的特点是它提供了许多的好处,不再要求用户去学习许多的新的语法。智能指针仍然能够像标准指针一样使用间接引用(使用*或者->)。例如,还是以前的例子,->操作符用于调用go()成员函数:

mySimpleSmartPtr-­>go();

与标准指针一样,也可以写成如下的语句:

(*mySimpleSmartPtr).go();

        get()成员函数也可以用于直接访问它包装的指针。这对于要求将指针传递给一个原始指针的情况会很有用。例如,假设你要使用如下的函数:

void processData(Simple* simple) { /* Use the simple pointer... */ }

你就可以像下面一样进行调用:

processData(mySimpleSmartPtr.get());

        可以对unique_ptr包装的指针进行释放,也可以用reset()将其指向另一个指针。举例如下:

mySimpleSmartPtr.reset();// Free resource and set to nullptr
mySimpleSmartPtr.reset(new Simple{}); // Free resource and set to a new
// Simple instance

        可以使用release()将unique_ptr包装的指针断开,返回包装指针指向的资源,然后将智能指针赋值为nullptr。非常有效,智能指针失去了对资源的控制,这样的话,在不再使用的时候,你就要负责将其资源进行释放!下面是一个例子:

Simple* simple { mySimpleSmartPtr.release() }; // Release ownership
// Use the simple pointer...
delete simple;
simple = nullptr;

        因为unique_ptr代表了唯一的属主,所以它不能被拷贝!但是,剧透一下,使用move的语法是可以将unique_ptr move给另一个的,这个我们以后再讨论。简单提一下,std::move()工具函数可以用于显式地将unique_ptr的属主进行转移,如下面的代码片断。别担心,其语法我们以后会讨论到,你会明白的。

class Foo
{
public:Foo(unique_ptr<int> data) : m_data { move(data) } { }
private:unique_ptr<int> m_data;
};auto myIntSmartPtr { make_unique<int>(42) };
Foo f { move(myIntSmartPtr) };

1.3、unique_ptr与C风格的数组

        unique_ptr可以保存动态分配的旧的C风格的数组。下面的例子生成了一个包含了动态分配的C风格的十个整数的数组的unique_ptr:

auto myVariableSizedArray { make_unique<int[]>(10) };

myVariableSizedArray的类型就是unique_ptr<int []>,支持用数组下标访问其元素。如下示例:

myVariableSizedArray[1] = 123;

        与非数组的情况一样,make_unique()对于数组的所有元素使用了值初始化,与std::vector类似。对于初始类型,这意味着初始化为0.如果不想生成缺省初始值的数组,可以调用make_unique_for_overwrite()函数,这意味着对于初始类型不进行初始化。要记住,要尽可能地避免不初始化数据,要理智使用。

        虽然可以使用unique_ptr来保存动态分配的C风格的数组,但还是推荐使用标准构造函数,如std::array或者vector。

1.4、对delete进行客户化

        缺省情况下,使用标准的new与delete操作符来分配与释放内存。但你可以改变这种行为,使用自己的分配与释放函数。当你 使用第三方C库时会很方便。例如,假设你有一个C库,要求你使用my_alloc()来分配内存,my_free()来释放内存:

int* my_alloc(int value) { return new int { value }; }
void my_free(int* p) { delete p; }

        为了在对的时间在分配了的资源上正确地调用my_fee(),可以使用带有客户化了的delete的unique_ptr:

unique_ptr<int, decltype(&my_free)> myIntSmartPtr { my_alloc(42), my_free };

        这段代码使用my_alloc()为整数分配了内存,通过调用my_free(),unique_ptr释放了内存。unique_ptr的这个属性对于非内存的其他资源的管理也很有用。例如,它可以用于自动关闭一个文件或者网络连接,或者任何其他资源,当unique_ptr不在活动范围时。

        不幸的是,unique_ptr的客户化的delete的语法有一点儿臃肿。需要指定客户化delete的类型作为模板类型参数,它应该是指向接受一个单独的指针作为参数的指针类型,并且返回void。在这个例子中,decltype(&my_free)用于返回my_free()函数的指针类型。使用带有shared_ptr的客户化的delete会更容易一点儿。我们明天会讨论的share_ptr会展示如何使用shard_ptr来自动关闭不在活动范围的文件。

相关文章:

C++学习笔记----6、内存管理(五)---- 智能指针(2)

书接上回&#xff01; make_unique()使用值初始化。例如&#xff0c;将初始类型初始化为0&#xff0c;对象为缺省构造。如果不需要这样的值初始化&#xff0c;例如&#xff0c;因为不管怎么样你都会覆写共初始值&#xff0c;你就可以省略值初始化&#xff0c;通过使用make_uniq…...

游戏出海迎新变局——海外游戏市场有哪些新趋势和新机遇?

游戏出海的热度越来越高&#xff0c;也面临着竞争加剧、门槛提升、成本增加的现实环境&#xff0c;游戏出海有哪些新变化和新趋势&#xff1f; 移动游戏出海的主要海外市场 在海外市场分布方面&#xff0c;美日韩仍然是我国移动游戏重要的海外市场&#xff0c;占据了中国出海…...

【Unity踩坑】创建新项目后提示编译错误要进入安全模式

在创建了新项目后&#xff08;比如URP&#xff0c;AR&#xff0c;VR&#xff09;&#xff0c;首次打开时提示有编译错误&#xff0c;要进入安全模式。 脚本是项目模板自带的&#xff0c;不会有问题。这时需要先选择进入安全模式&#xff0c;然后关闭项目&#xff0c;重新打开就…...

SpringBoot开发——整合Logbook进行HTTP API请求响应日志输出

文章目录 1. 简介依赖管理2. 实战案例2.1 基本用法2.2 结合Logback日志记录到文件2.3 自定义核心类Logbook2.4 自定义日志输出Sink2.5 与RestTemplate集成1. 简介 记录HTTP API请求响应日志对于监控、调试和性能优化至关重要。它帮助开发者追踪API的使用情况,包括请求来源、参…...

【嵌入式开发 Linux 常用命令系列 7.1 -- git log 只显示日期和主题(title)和commit id】

文章目录 git log 只显示日期和主题(title)和commit id示例其他日期格式选项 git log 只显示日期和主题(title)和commit id 要使用 git log 仅显示提交的日期、提交消息&#xff08;title&#xff09;和提交号&#xff08;commit hash&#xff09;&#xff0c;你可以使用自定义…...

Android Radio2.0——交通公告状态设置(二)

通过前面的学习,我们知道在 Radio 广播中,交通公告(Traffic Announcement, TA)是一个比较重要的概念,它和交通广播(Traffic Radio)是相关的概念,但它们并不完全相同。 一、简介 1、概念介绍 交通公告 定义:交通公告是指在广播中插入的特别信息,通常是关于交通状况…...

用centos安装远程迅雷失败,重写程序做一台下载服务器

安装远程迅雷的时候&#xff0c;要不是安装包地址过期&#xff0c;就是出现64不兼容32的libz.so.1的包&#xff0c;而且32位的libz包也是好多网站过期。 没办法用仅有的python3&#xff0c;用flask搭建了一个小型的内网下载服务器&#xff0c;当然&#xff0c;只要路由器做映射…...

Mysql基础练习题 1407.排名靠前的旅行者(力扣)

编写解决方案&#xff0c;报告每个用户的旅行距离。 # 返回的结果表单&#xff0c;以 travelled_distance 降序排列 &#xff0c;如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 。 题目链接&#xff1a; https://leetcode.cn/problems/top-travellers/d…...

一维稳态与非稳态导热的详细分析

目录 引言 一维稳态导热 应用实例&#xff1a;单层平壁导热 数值求解&#xff1a; 一维非稳态导热 应用实例&#xff1a;单层平壁的非稳态导热 温度变化阶段 表格总结&#xff1a; 引言 热传导&#xff08;Heat Conduction&#xff09;是热量在物体内部通过微观粒子的相…...

以太坊开发环境

1. 测试网络 可以使用以下命令将以太坊的 Go 语言客户端 Geth 连接到测试网络 [admindaolian ~]$geth --testnet 下图显示了示例输出&#xff0c;该图显示了所选网络的类型以及有关区块链下载的其他各种信息。 Geth 客户端的下载地址如下&#xff1a; https://geth.ethereum…...

深入理解Java虚拟机:Jvm总结-虚拟机字节码执行引擎

第八章 虚拟机字节码执行引擎 8.1 意义 不受物理条件制约地定制指令集与执行引擎的结构体系&#xff0c;能够执行那些不被硬件直接支持的指令集格式。输入的是字节码二进制流&#xff0c;处理过程是字节码解析执行的等效过程&#xff0c;输出的是执行结果 8.2 运行时栈帧结构…...

第十一周:机器学习

第十一周周报 摘要Abstract机器学习1. 注意力机制&#xff08;下&#xff09;1.1 multi-head self-attention&#xff08;多头注意力机制&#xff09;1.2 Positional Encoding&#xff08;位置编码&#xff09;1.3 truncated self attention&#xff08;截断式注意力机制&#…...

碰撞检测 | 详解圆-矩形碰撞检测与N圆覆盖模型(附ROS C++可视化)

目录 0 专栏介绍1 N N N圆覆盖碰撞模型2 圆与矩形的碰撞检测3 算法仿真与可视化3.1 核心算法3.2 仿真实验 0 专栏介绍 &#x1f525;课设、毕设、创新竞赛必备&#xff01;&#x1f525;本专栏涉及更高阶的运动规划算法轨迹优化实战&#xff0c;包括&#xff1a;曲线生成、碰…...

pandas读取Excel文件单元格中的百分数时保持数据格式及精度

pandas读取Excel文件单元格中的百分数时保持数据格式及精度 在使用Pandas读取Excel文件时,通常Excel中的百分数会被转换为浮点数。在这种情况下,如果你希望保留数据的格式和精度,有几个步骤可以帮助你实现这个目标: 读取数据:使用Pandas的read_excel函数来读取Excel文件。…...

【重学 MySQL】二十五、等值连接vs非等值连接、自连接vs非自连接

【重学 MySQL】二十五、等值连接vs非等值连接、自连接vs非自连接 等值连接&#xff08;Equijoin&#xff09; vs 非等值连接&#xff08;Non-equijoin&#xff09;等值连接&#xff08;Equijoin&#xff09;非等值连接&#xff08;Non-equijoin&#xff09; 自连接&#xff08;…...

Springboot工程配置https访问

背景 因为前端工程使用nginx配置了https访问&#xff0c;在https直接请求我们Springboot后端的http接口会报错。那么我们就需要配置使得我们后端的springboot服务支持https访问。 证书生成 在配置springboot工程https之前&#xff0c;我们需要生成自签名证书以及Spring Boot…...

智慧水务建设的核心内容

智慧水务解决方案的主要对象客户是全国各地水务投资集团、水务局、水司、水厂、农水办,也会有少量项目涉及到住建局或城管局。解决方案通常会以具体的某个业务单位的职能工作为切入点,配合物联感知、大数据分析、人工智能等技术手段,为城市供水、乡村供水的水质安全、供水调…...

opencv之图像轮廓

文章目录 前言查找并绘制轮廓查找图像轮廓&#xff1a;findContours函数绘制图像轮廓&#xff1a;drawContours函数轮廓实例 矩特征Hu矩Hu矩函数形状匹配 前言 图像轮廓指的是图像中物体边缘或形状的外部线条&#xff0c;通常通过图像处理技术来检测和提取。轮廓是用于描述物体…...

shader 案例学习笔记之step函数

step函数 参数是float step(edge,x)&#xff1a;当x>edge时返回1&#xff0c;否则返回0 #ifdef GL_ES precision mediump float; #endifuniform vec2 u_resolution;void main(){vec2 st gl_FragCoord.xy/u_resolution.xy;float f step(0.5, st.x);gl_FragColor vec4(f…...

node快速复制文件或文件夹,排除部分文件(node_modules)

const fs require(fs) const path require(path)/*** description: 获取完整的文件路径* param {*} url 路径* return {*} 返回完整的文件路径*/ const getPath (url) > {return path.join(__dirname, url) }/*** description: 获取参数* return {*} target【目标文件夹】…...

微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】

微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来&#xff0c;Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

高等数学(下)题型笔记(八)空间解析几何与向量代数

目录 0 前言 1 向量的点乘 1.1 基本公式 1.2 例题 2 向量的叉乘 2.1 基础知识 2.2 例题 3 空间平面方程 3.1 基础知识 3.2 例题 4 空间直线方程 4.1 基础知识 4.2 例题 5 旋转曲面及其方程 5.1 基础知识 5.2 例题 6 空间曲面的法线与切平面 6.1 基础知识 6.2…...

论文笔记——相干体技术在裂缝预测中的应用研究

目录 相关地震知识补充地震数据的认识地震几何属性 相干体算法定义基本原理第一代相干体技术&#xff1a;基于互相关的相干体技术&#xff08;Correlation&#xff09;第二代相干体技术&#xff1a;基于相似的相干体技术&#xff08;Semblance&#xff09;基于多道相似的相干体…...

使用Spring AI和MCP协议构建图片搜索服务

目录 使用Spring AI和MCP协议构建图片搜索服务 引言 技术栈概览 项目架构设计 架构图 服务端开发 1. 创建Spring Boot项目 2. 实现图片搜索工具 3. 配置传输模式 Stdio模式&#xff08;本地调用&#xff09; SSE模式&#xff08;远程调用&#xff09; 4. 注册工具提…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...

2025年低延迟业务DDoS防护全攻略:高可用架构与实战方案

一、延迟敏感行业面临的DDoS攻击新挑战 2025年&#xff0c;金融交易、实时竞技游戏、工业物联网等低延迟业务成为DDoS攻击的首要目标。攻击呈现三大特征&#xff1a; AI驱动的自适应攻击&#xff1a;攻击流量模拟真实用户行为&#xff0c;差异率低至0.5%&#xff0c;传统规则引…...

break 语句和 continue 语句

break语句和continue语句都具有跳转作用&#xff0c;可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...

使用python进行图像处理—图像变换(6)

图像变换是指改变图像的几何形状或空间位置的操作。常见的几何变换包括平移、旋转、缩放、剪切&#xff08;shear&#xff09;以及更复杂的仿射变换和透视变换。这些变换在图像配准、图像校正、创建特效等场景中非常有用。 6.1仿射变换(Affine Transformation) 仿射变换是一种…...

Ubuntu 安装 Mysql 数据库

首先更新apt-get工具&#xff0c;执行命令如下&#xff1a; apt-get upgrade安装Mysql&#xff0c;执行如下命令&#xff1a; apt-get install mysql-server 开启Mysql 服务&#xff0c;执行命令如下&#xff1a; service mysql start并确认是否成功开启mysql,执行命令如下&am…...