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

【C++11】 initializer_list | 右值引用 | 移动构造 | 完美转发

文章目录

    • 1. 统一的列表初始化
      • { } 初始化
      • initializer_list
    • 2. 引用
      • 左值引用
      • 右值引用
      • 左值引用与右值引用的相互转换
      • 右值引用的真正使用场景
        • 移动构造
      • C++98与C++11传值返回问题
      • 注意事项
      • 总结
    • 3. 完美转发

1. 统一的列表初始化

{ } 初始化

C++11 扩大了括号括起的列表(初始化列表)的使用范围,使其可用于所有的内置类型和用户自定义类型,
使用初始化列表,可添加等号(=),也可不添加

将1赋值给x1,x2处省略了赋值符号,将5赋值给x2
同样也可以将new开辟4个int的空间初始化为0


创建对象时,可以使用列表初始化方式调用构造函数初始化,也可省略等号

initializer_list

花括号里面的常量数组,C++可以将其识别成一个类型 initializer_list,
initializer_list这个类带有模板参数,因为传过来的int数据,所以为 initializer_list


类中存在两个指针
size作为两个指针相减
begin指向开始的位置,end 指向结束位置的下一个


对数据不能修改,说明指向的内容在常量区
任意的常量数组 都可以赋值给 initializer_list的对象


在这里插入图片描述

C++11中 的vector,是 通过新增的构造函数的方式 使用 initializer_list 进行初始化

2. 引用

左值引用

左值引用就是给左值取别名
左值是一个数据的表达式(如变量名或者引用指针)
可以获取它的地址 即为左值


左值出现赋值符号的左边 (也可出现在右边)


右值引用

右值也是一个表示数据的表达式(如字面常量、表达式返回值、函数返回值)
右值可以出现在赋值符号的右边,但不能出现赋值符号的左边,右值不能取地址

右值引用 就是 给右值起别名


左值引用与右值引用的相互转换

x+y 作为右值 ,左值引用是无法直接引用右值的
但可以通过隐式类型转换的方式,由于 临时变量具有常性, 加入 const 即可


a作为左值, 右值引用是无法直接引用左值, 使用move 后,其返回值作为右值

右值引用的真正使用场景

虽然可以在左值中加入const ,既可以使用左值 ,又可以使用右值
但是 无法区分到底是左值还是右值的


加入右值引用后,传参过程中,更好的进行参数匹配
就可以 区分 是调用 左值引用 还是 右值引用


移动构造

右值分为两种
1.纯右值(内置类型)
2.将亡值(自定义类型)


s1作为左值,调用拷贝构造
s1+s2 作为表达式返回值,代表右值 即 将亡值


若右值进行深拷贝,(再创建一块空间在原有的数据拷贝过来,然后释放原有空间),
将亡值 是没有必要拷贝,代价太大了


在这里插入图片描述
由于有const,所以无论是左值还是右值都可以传过来作为参数


将右值(将亡值) 的资源进行转移ret2
使用右值引用 区分出右值后,就没有必要进行深拷贝了 ,
接收右值 作为参数 的拷贝 称为 移动拷贝


在这里插入图片描述
调用移动构造,进行移动拷贝


在这里插入图片描述
右值就不再调用深拷贝,而是使用移动拷贝

C++98与C++11传值返回问题

在这里插入图片描述
对于传值返回,C++98 刚开始会进行两次拷贝构造,
编译器优化后,会进行一次拷贝构造


在这里插入图片描述

编译器不优化时
str作为临时变量 属于左值, 将str传给 临时变量 ,属于拷贝构造
临时对象 是看不见摸不着的 无法知道它的地址 ,所以属于 右值 (将亡值) ,
所以将右值传给 str ,属于 移动构造

编译器优化时
编译器会想办法将 函数中的临时变量 str 识别成 右值(使用move其函数返回值为右值),进行移动构造 (资源转移)


在这里插入图片描述
s2 进行深拷贝 ,将s1的数据拷贝到新开辟的空间中
move(s1)后,表达式返回值作为右值
s3 进行移动拷贝,把s1的资源转移到s3中,所以导致s1为空

注意事项

右值是不可以取地址的,但是给右值取别名后,会导致右值存储到特定位置,并且可以取到该位置地址
如:不能取到字面常量10的地址,但是ret引用后,可以对ret取地址,也可以修改ret,如果像ret不能修改,需要加入const 即 const int &&

总结

左值引用减少拷贝,提高效率
右值引用也是减少拷贝,提高效率
但角度不同,
左值引用是直接减少拷贝
右值引用是间接减少拷贝,识别出是左值还是右值,若识别出是右值,则不再深拷贝,
直接移动拷贝(资源转移),提高效率

3. 完美转发

写一个函数 ,无论传过来的参数为左值还是右值,都可以接受 (将左值move后,返回值为右值)

当左值作为参数 时, 会发生引用折叠,调用 fun(t),此时t作为左值,所以会输出 左值引用


当右值作为参数时,实际上右值接收后,要进行移动拷贝,右值引用 引用后属性会变成左值,否则无法进行资源转移


调用push_back ,参数为右值,右值引用 引用后属性会变成左值,但是 变为左值为了进行 资源转移的 ,
还没等进行转移, 在这期间先调用 insert ,(x作为左值),调用左值引用的insert 就会导致 进行深拷贝,而不是进行移动拷贝


C++支持 完美转发 ,用于保持原有的属性,避免 参数x在资源转移之前 转过早的情况


所以当此时fun 参数 加入forward 完美转发后,使右值 引用后,并没有立即变为左值,而是保持原有的属性 右值
所以 调用 对应的fun 打印 右值引用

相关文章:

【C++11】 initializer_list | 右值引用 | 移动构造 | 完美转发

文章目录 1. 统一的列表初始化{ } 初始化initializer_list 2. 引用左值引用右值引用左值引用与右值引用的相互转换右值引用的真正使用场景移动构造 C98与C11传值返回问题注意事项总结 3. 完美转发 1. 统一的列表初始化 { } 初始化 C11 扩大了括号括起的列表(初始化列表)的使用…...

基于html+css的图展示122

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…...

《Unix环境高级编程》/bin/sh: ./fixup.awk: Permission denied

我的代码是从http://www.apuebook.com/code3e.html下载的,先是在 使用cat /etc/redhat-release看到操作系统是CentOS Linux 7.6,使用uname -r看到内核是3.10.0-957.el7.x86_64。 在代码顶级目录下,执行make。 发现报错: ./fi…...

万字长文+示例代码详解DDD中常用的架构(含代码示例)

目录 分层架构(Layered Architecture) 概念 示例代码 总结 领域驱动设计的六边形架构(Hexagonal Architecture) 概念 示例代码 总结 CQRS(Command Query Responsibility Segregation) 概念 示例…...

Debezium UI On ECS编译安装及开放Web访问

1. 访问debezium-ui的代码仓库,下载源码 GitHub - debezium/debezium-ui: A web UI for Debezium; Please log issues at https://issues.redhat.com/browse/DBZ. 2. 解压zip源码包: TEST[hadoopshdcvfsla1894 ~]$ cd /data/module TEST[hadoopshd…...

【支付系统】核心支付流程

支付在产品中常见的用处为购买和充值.这两种功能操作大相径庭,其中购买相对充值多了很多步骤,它需要锁商品或者库存,还需要超时未支付取消订单等操作.在这篇文章中主要探讨支付部分,属于购买和充值公共部分. 下面是绘制的简易支付时序图 以上时序图并非完整,其实核心步骤就是, …...

电脑系统可以直接备份到其它硬盘上吗

在日常使用电脑的过程中,我们都希望能够保护好重要的系统数据,以防止意外数据丢失或系统崩溃。那么,能否将电脑系统直接备份到其他硬盘上呢?本文将为您解答这个问题,并探讨备份系统的方法和注意事项。 工具/原料&…...

springboot项目如何优雅停机

文章目录 前言kill -9 pid的危害如何优雅的停机理论步骤优雅方式1、kill -15 pid 命令停机2、ApplicationContext close停机3、actuator shutdown 停机4、ApplicationListener 监听延时停机 前言 相信很多同学都会用Kill -9 PID来杀死进程,如果用在我们微服务项目里…...

springboot mybatis-plus 代码生成工具

介绍 基于mybatis-plus代码生成工具 后续会不断完善 规划 后续会基于此功能搞低代码平台,会有前端VUE mybatis-plus介绍&特性 • 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑 • 损耗小&#xff1…...

超全、超详细的Redis学习笔记总结

❤ 作者主页:欢迎来到我的技术博客😎 ❀ 个人介绍:大家好,本人热衷于Java后端开发,欢迎来交流学习哦!( ̄▽ ̄)~* 🍊 如果文章对您有帮助,记得关注、点赞、收藏、…...

Day05 04-MySQL分库分表介绍

文章目录 第十七章 MySQL分库分表17.1 什么是分库分表17.2 为什么要分库分表17.3 垂直切分17.3.1 垂直分库17.3.2 垂直分表 17.4 水平切分17.4.1 水平分库17.4.2 水平分表17.4.3 常见的水平切分规则 第十七章 MySQL分库分表 17.1 什么是分库分表 MySQL数据库常见的优化方案中…...

基于SpringBoot+vue的毕业生信息招聘平台设计和实现

博主介绍: 大家好,我是一名在Java圈混迹十余年的程序员,精通Java编程语言,同时也熟练掌握微信小程序、Python和Android等技术,能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…...

git一定要学会,加油

gitgit文档http://file:///F:/%E8%B5%84%E6%96%99%E5%A4%8D%E4%B9%A0/Git%E4%BC%98%E7%A7%80%E5%BC%80%E6%BA%90%E4%B9%A6%E7%B1%8D/Git%E5%BC%80%E6%BA%90%E4%B9%A6%E7%B1%8D/Pro%20Git%E4%B8%AD%E6%96%87PDF%E7%89%88.pdf init 初始化仓库 这个命令在当前目录下初始化一个 G…...

TVM面试题

1、TVM中的调度器(Scheduler)是什么?请简要解释TVM调度器的作用和工作原理。 TVM中的调度器(Scheduler)是负责将计算图映射到特定硬件目标上的组件。调度器在TVM中起着关键的作用,它决定了计算图的执行方式、并行化策略以及内存布局等,以优化…...

CSS相关面试题

1、标准盒子模型和IE怪异盒子模型? 标准盒子模型就是指的元素的宽度和高度仅包括的内容区域,不包括边框和内边距,也就是说,元素的实际宽度和高度等于内容区域的宽度和高度IE怪异盒子是指元素的高度和宽度,包括内容区域…...

6.11总结

这周准备了蓝桥杯,主要看了一些以前学过的东西,看了二分,树状数组,树状数组二分,复习了利用倍增相关的算法。 周六去打的蓝桥杯,总体来说也就一般吧,出了考场突然想起来我b题中间的称号写成了加…...

Hazel游戏引擎(008-009)事件系统

文中若有代码、术语等错误,欢迎指正 文章目录 008、事件系统-设计009、事件系统-自定义事件前言自定义事件类与使用声明与定义类代码包含头文件使用事件 事件调度器代码 C知识:FunctionBind用法function基本使用 012、事件系统-DemoLayer用EventDispache…...

【C++】 STL(上)STL简述、STL容器

文章目录 简述STL容器list链表vector向量deque双端队列map映射表set集合hash_map哈希表 简述 STL是“Standard Template Library”的缩写,中文译为“标准模板库”。STL是C标准库的一部分,位与各个C的头文件中,即他并非以二进制代码的形式提供…...

【002 基础知识】什么是原子操作?

一、原子操作 原子操作就是指不能再进一步分割的操作。 二、为了实现一个互斥,自己定义一个变量作为标记来作为一个资源只有一个使用者行不行? 不行。如果在一个线程正持有锁时(2处),线程上下文发生切换&#xff0c…...

English Learning - L3 作业打卡 Lesson5 Day32 2023.6.5 周一

English Learning - L3 作业打卡 Lesson5 Day32 2023.6.5 周一 引言🍉句1: What do you read when you are travelling by train or bus?成分划分弱读爆破语调 🍉句2: What are other passengers reading?成分划分弱读连读语调 🍉句3: Perh…...

逻辑回归:给不确定性划界的分类大师

想象你是一名医生。面对患者的检查报告(肿瘤大小、血液指标),你需要做出一个**决定性判断**:恶性还是良性?这种“非黑即白”的抉择,正是**逻辑回归(Logistic Regression)** 的战场&a…...

线程同步:确保多线程程序的安全与高效!

全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分&#xff…...

Mybatis逆向工程,动态创建实体类、条件扩展类、Mapper接口、Mapper.xml映射文件

今天呢,博主的学习进度也是步入了Java Mybatis 框架,目前正在逐步杨帆旗航。 那么接下来就给大家出一期有关 Mybatis 逆向工程的教学,希望能对大家有所帮助,也特别欢迎大家指点不足之处,小生很乐意接受正确的建议&…...

无人机侦测与反制技术的进展与应用

国家电网无人机侦测与反制技术的进展与应用 引言 随着无人机(无人驾驶飞行器,UAV)技术的快速发展,其在商业、娱乐和军事领域的广泛应用带来了新的安全挑战。特别是对于关键基础设施如电力系统,无人机的“黑飞”&…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南:计算机基础与源码原理深度解析 第一轮提问:基础概念问题 1. 请解释什么是进程和线程的区别? 面试官:进程是程序的一次执行过程,是系统进行资源分配和调度的基本单位;而线程是进程中的…...

Python 实现 Web 静态服务器(HTTP 协议)

目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像(比如分辨率3000*3000的图像)的办法,尤其是想把内存中的裸数据(只有图像的数据,不包…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址:LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂,正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...

API网关Kong的鉴权与限流:高并发场景下的核心实践

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 引言 在微服务架构中,API网关承担着流量调度、安全防护和协议转换的核心职责。作为云原生时代的代表性网关,Kong凭借其插件化架构…...

微服务通信安全:深入解析mTLS的原理与实践

🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、引言:微服务时代的通信安全挑战 随着云原生和微服务架构的普及,服务间的通信安全成为系统设计的核心议题。传统的单体架构中&…...