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)
书接上回! make_unique()使用值初始化。例如,将初始类型初始化为0,对象为缺省构造。如果不需要这样的值初始化,例如,因为不管怎么样你都会覆写共初始值,你就可以省略值初始化,通过使用make_uniq…...

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

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

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 仅显示提交的日期、提交消息(title)和提交号(commit hash),你可以使用自定义…...
Android Radio2.0——交通公告状态设置(二)
通过前面的学习,我们知道在 Radio 广播中,交通公告(Traffic Announcement, TA)是一个比较重要的概念,它和交通广播(Traffic Radio)是相关的概念,但它们并不完全相同。 一、简介 1、概念介绍 交通公告 定义:交通公告是指在广播中插入的特别信息,通常是关于交通状况…...

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

Mysql基础练习题 1407.排名靠前的旅行者(力扣)
编写解决方案,报告每个用户的旅行距离。 # 返回的结果表单,以 travelled_distance 降序排列 ,如果有两个或者更多的用户旅行了相同的距离, 那么再以 name 升序排列 。 题目链接: https://leetcode.cn/problems/top-travellers/d…...

一维稳态与非稳态导热的详细分析
目录 引言 一维稳态导热 应用实例:单层平壁导热 数值求解: 一维非稳态导热 应用实例:单层平壁的非稳态导热 温度变化阶段 表格总结: 引言 热传导(Heat Conduction)是热量在物体内部通过微观粒子的相…...

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

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

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

碰撞检测 | 详解圆-矩形碰撞检测与N圆覆盖模型(附ROS C++可视化)
目录 0 专栏介绍1 N N N圆覆盖碰撞模型2 圆与矩形的碰撞检测3 算法仿真与可视化3.1 核心算法3.2 仿真实验 0 专栏介绍 🔥课设、毕设、创新竞赛必备!🔥本专栏涉及更高阶的运动规划算法轨迹优化实战,包括:曲线生成、碰…...
pandas读取Excel文件单元格中的百分数时保持数据格式及精度
pandas读取Excel文件单元格中的百分数时保持数据格式及精度 在使用Pandas读取Excel文件时,通常Excel中的百分数会被转换为浮点数。在这种情况下,如果你希望保留数据的格式和精度,有几个步骤可以帮助你实现这个目标: 读取数据:使用Pandas的read_excel函数来读取Excel文件。…...

【重学 MySQL】二十五、等值连接vs非等值连接、自连接vs非自连接
【重学 MySQL】二十五、等值连接vs非等值连接、自连接vs非自连接 等值连接(Equijoin) vs 非等值连接(Non-equijoin)等值连接(Equijoin)非等值连接(Non-equijoin) 自连接(…...
Springboot工程配置https访问
背景 因为前端工程使用nginx配置了https访问,在https直接请求我们Springboot后端的http接口会报错。那么我们就需要配置使得我们后端的springboot服务支持https访问。 证书生成 在配置springboot工程https之前,我们需要生成自签名证书以及Spring Boot…...

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

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

shader 案例学习笔记之step函数
step函数 参数是float step(edge,x):当x>edge时返回1,否则返回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【目标文件夹】…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
Linux链表操作全解析
Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表?1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

从WWDC看苹果产品发展的规律
WWDC 是苹果公司一年一度面向全球开发者的盛会,其主题演讲展现了苹果在产品设计、技术路线、用户体验和生态系统构建上的核心理念与演进脉络。我们借助 ChatGPT Deep Research 工具,对过去十年 WWDC 主题演讲内容进行了系统化分析,形成了这份…...
Golang dig框架与GraphQL的完美结合
将 Go 的 Dig 依赖注入框架与 GraphQL 结合使用,可以显著提升应用程序的可维护性、可测试性以及灵活性。 Dig 是一个强大的依赖注入容器,能够帮助开发者更好地管理复杂的依赖关系,而 GraphQL 则是一种用于 API 的查询语言,能够提…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

【JavaWeb】Docker项目部署
引言 之前学习了Linux操作系统的常见命令,在Linux上安装软件,以及如何在Linux上部署一个单体项目,大多数同学都会有相同的感受,那就是麻烦。 核心体现在三点: 命令太多了,记不住 软件安装包名字复杂&…...
Element Plus 表单(el-form)中关于正整数输入的校验规则
目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入(联动)2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数
高效线程安全的单例模式:Python 中的懒加载与自定义初始化参数 在软件开发中,单例模式(Singleton Pattern)是一种常见的设计模式,确保一个类仅有一个实例,并提供一个全局访问点。在多线程环境下,实现单例模式时需要注意线程安全问题,以防止多个线程同时创建实例,导致…...

用机器学习破解新能源领域的“弃风”难题
音乐发烧友深有体会,玩音乐的本质就是玩电网。火电声音偏暖,水电偏冷,风电偏空旷。至于太阳能发的电,则略显朦胧和单薄。 不知你是否有感觉,近两年家里的音响声音越来越冷,听起来越来越单薄? —…...