当前位置: 首页 > 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【目标文件夹】…...

连锁超市冷库节能解决方案:如何实现超市降本增效

在连锁超市冷库运营中&#xff0c;高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术&#xff0c;实现年省电费15%-60%&#xff0c;且不改动原有装备、安装快捷、…...

苍穹外卖--缓存菜品

1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得&#xff0c;如果用户端访问量比较大&#xff0c;数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据&#xff0c;减少数据库查询操作。 缓存逻辑分析&#xff1a; ①每个分类下的菜品保持一份缓存数据…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

EtherNet/IP转DeviceNet协议网关详解

一&#xff0c;设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络&#xff0c;本网关连接到EtherNet/IP总线中做为从站使用&#xff0c;连接到DeviceNet总线中做为从站使用。 在自动…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)

骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术&#xff0c;它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton)&#xff1a;由层级结构的骨头组成&#xff0c;类似于人体骨骼蒙皮 (Mesh Skinning)&#xff1a;将模型网格顶点绑定到骨骼上&#xff0c;使骨骼移动…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

【Go语言基础【13】】函数、闭包、方法

文章目录 零、概述一、函数基础1、函数基础概念2、参数传递机制3、返回值特性3.1. 多返回值3.2. 命名返回值3.3. 错误处理 二、函数类型与高阶函数1. 函数类型定义2. 高阶函数&#xff08;函数作为参数、返回值&#xff09; 三、匿名函数与闭包1. 匿名函数&#xff08;Lambda函…...

JavaScript 数据类型详解

JavaScript 数据类型详解 JavaScript 数据类型分为 原始类型&#xff08;Primitive&#xff09; 和 对象类型&#xff08;Object&#xff09; 两大类&#xff0c;共 8 种&#xff08;ES11&#xff09;&#xff1a; 一、原始类型&#xff08;7种&#xff09; 1. undefined 定…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...