[ C++ ] | C++11 从左值引用到右值引用

(目录占位)

1. 前言:

C++ 11 是在 C++ 98 之后又一个变化比较大的标准。为C++增加了很多东西,其中有一部分是有用的,有一部分是我自认为作用不是很大东西。这一章呢?我们就来说说C++11我,我认为对性能优化最有用的一部分 ---- 右值引用

2. 简单回顾:左值引用

左值?我们现在说说什么是左值?

直接抛结论:能取地址的值或者表达式结果就是左值。左值可以出现在 = 左边,也可以出现在 = 右边,不能仅仅以 = 号来区分左右值。

最开始时候的引用,就是左值引用,在C++的语法层面上,引用是给一个变量起一个别名,是不开辟空间的,目的是为了:减少拷贝,提高效率

我们通常在学习的时候与 指针 对照学习。

语法层面(指针对比引用):

引用在定义的时候必须初始化,指针在定义的时候是可以不初始化的。

引用是没有空引用的,但是指针呢?他是有空指针的,比如C++11之前的NULL和C++11提供的nullptr。

引用是不开辟空间的,但是指针是需要开辟4个字节或者8个字节的空间的。

引用和指针都有一个概念:权限的方法和缩小,首先一说,只有引用和指针有权限的放大和缩小。其他的语法是没有的,我们在学习的时候,千万不要自己创造语法...

权限的放大:
#include <iostream>int main()
{const int a = 10;int &b = a; // 权限的放大const int c = 20;int *p = &c; // 权限的放大return 0;
}

变量 a 的权限是 可读, 但是 变量 b 作为变量 a 的引用,权限却是可读可写。 

变量 c 的权限是 可读, 但是 变量 p 指向 变量 a,权限却是可读可写。

上面这两种情况都是编译器默认不被允许的。 

权限的缩小:
#include <iostream>int main()
{int a = 10;const int &b = a; // 权限的缩小int c = 20;const int *p = &c; // 权限的缩小return 0;
}

变量 a 的权限是 可读可写, 但是 变量 b 作为变量 a 的引用,权限是可读。 

变量 c 的权限是 可读可写, 但是 变量 p 指向 变量 c,权限是可读。

上面的这两种情况是编译器默认被允许的。

小结:

权限的放大是不被允许的,但是权限的缩小是被允许的。

权限的放大和缩小都是语法层面的概念,都是被编译器约束的,我们可以通过强制类型转换来放大或者缩小权限(但是不推荐,因为有风险),都只是为了“骗”过编译器。

汇编层面:

引用和指针是一个的,都是开辟可一块空间,用来保存地址,指针变量就是用来保存指向的对象的地址,引用也是一样的,开辟一块空间,用来保存被起别名的对象的地址。

3. 本章主角:右值引用

相对于左值来说,右值就是不能取地址的值,并且右值是不能出现在 = 号的左边的。

自定义类型的右值常见的两种形式 : 临时对象 匿名对象

C++11 对右值又做了细分:纯右值(内置类型) 和将亡值(自定义类型),我们的主要研究对象就是:将亡值(自定义类型)

编译器在进化过程中,将 拷贝构造 + 构造 优化成 直接构造

比如说在函数栈帧内返回一个比较大的对象的时候,右值引用的价值就极大了。

{

       原来: 跨行的:构造 + 拷贝构造

       现在: 跨行的:构造 + 移动构造

}

减少了一次拷贝,还是很可观的。

移动构造,移动赋值

有了移动构造之后: 返回时先拷贝构造生成临时对象,用临时对象移动构造

如果 “析构函数”,“拷贝构造”,“拷贝赋值” 都没有实现编译器就会自动生成 “移动构造”

编译器生成的移动构造:内置类型去值拷贝,自定义类型去调用它自己的移动构造

为什么?

需要显式写析构,说明有资源要释放,说明需要显式写拷贝构造重载

说明要显式写移动构造移动赋值

要么都自己写,要么都编译器自己生成。

4. 左值引用和右值引用

这个部分我们主要讨论一下,左值引用是否能引用右值,右值引用是否能引用左值,就是是否能交叉?

先看右值引用能否引用左值?

但是这样:const 左值引用 可以给引用右值 是可以的

除了这样,我们还可以通过强制类型转换来让左值引用引用右值,右值引用引用左值。

5. 小结

左值引用和右值引用的目的都是为了:减少拷贝,提高效率。但是他们都是编译器层面的概念,是可以通过强制类型转化来转化的(骗编译器,不建议)。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于MCU实现的电机转速精确控制方案:软件设计与实现

本文将详细介绍一篇基于微控制器&#xff08;MCU&#xff09;的电机转速精确控制的软件方案。通过采样PWM信号控制和ADC采样技术&#xff0c;结合PID闭环控制算法&#xff0c;实现了电机转速的高效、稳定调节。以下是软件方案流程图&#xff0c;下文将对其进行展开讲解。 原图太…

Jmeter触发脚本备份

JMeter 在以下情况会触发脚本备份&#xff1a; 手动保存测试计划时&#xff1a;如果测试计划有未保存的修改&#xff0c;当用户手动保存测试计划&#xff08;脚本&#xff09;时&#xff0c;JMeter 都会自动将当前脚本备份到${JMETER_HOME}/backups文件夹下。 关闭 JMeter 时…

AI人工智能-PyCharm的介绍安装应用

下载与安装 创建python项目 项目路径&#xff1a;C:\Users\miloq\Desktop\python_project 配置环境 提前找到conda配置的python-base路径 配置conda环境 运行项目 运行结果

Flink内存模型--flink1.19.1

Flink 的 JobManager 和 TaskManager 在内存分配上有不同的职责和结构。以下是两者的内存分类及详细说明&#xff1a; 一、JobManager 内存分类 JobManager 主要负责作业调度、协调&#xff08;如 Checkpoint 协调&#xff09;、资源管理等&#xff0c;其内存需求相对较低&…

华为数字化转型-方法篇

1 方法篇-3-愿景驱动的数字化转型规划 1.2 业务战略是数字化转型的龙头 1.3 数字时代&#xff0c;企业需要适时地调整业务战略 1.3.1 引入数字化商业模式 引入数字化商业模式包括改变与客户做生意的方式&#xff0c;改变销售的渠道&#xff0c;基于产业互联网重新定位与行 业…

常用的排序算法------练习4

1. 题目 2. 思路和题解 这道题是很经典的荷兰国旗问题&#xff0c;根据题目意思&#xff0c;要对这个数组按照颜色排序&#xff0c;而此时现在的红、白、蓝三个颜色分别对应0&#xff0c;1&#xff0c;2&#xff0c;因此可以想到使用冒泡排序对该数组进行排序。 代码如下&…

传统神经网络、CNN与RNN

在网络上找了很多关于深度学习的资料&#xff0c;也总结了一点小心得&#xff0c;于是就有了下面这篇文章。这里内容较为简单&#xff0c;适合初学者查看&#xff0c;所以大佬看到这里就可以走了。 话不多说&#xff0c;上图 #mermaid-svg-Z3k5YhiQ2o5AnvZE {font-family:&quo…

1371. 货币系统-dp背包问题

给定 V种货币&#xff08;单位&#xff1a;元&#xff09;&#xff0c;每种货币使用的次数不限。 不同种类的货币&#xff0c;面值可能是相同的。 现在&#xff0c;要你用这 V种货币凑出 N 元钱&#xff0c;请问共有多少种不同的凑法。 输入格式 第一行包含两个整数 V 和 N…

python和Java的区别

Python和Java是两种流行的编程语言&#xff0c;它们之间有一些重要的区别&#xff1a; 语法&#xff1a;Python是一种动态类型的脚本语言&#xff0c;语法简洁明了&#xff0c;通常使用缩进来表示代码块。Java是一种静态类型的编程语言&#xff0c;语法更为严格&#xff0c;需要…

正则化是什么?

正则化&#xff08;Regularization&#xff09;是机器学习中用于防止模型过拟合&#xff08;Overfitting&#xff09;的一种技术&#xff0c;通过在模型训练过程中引入额外的约束或惩罚项&#xff0c;降低模型的复杂度&#xff0c;从而提高其泛化能力&#xff08;即在未见数据上…

计算机网络——传输层(TCP)

传输层 在计算机网络中&#xff0c;传输层是将数据向上向下传输的一个重要的层面&#xff0c;其中传输层中有两个协议&#xff0c;TCP&#xff0c;UDP 这两个协议。 TCP 话不多说&#xff0c;我们直接来看协议报头。 源/目的端口号&#xff1a;表示数据从哪个进程来&#xff0…

界面控件DevExpress WinForms v25.1 - 人工智能(AI)方面全新升级

DevExpress WinForms拥有180组件和UI库&#xff0c;能为Windows Forms平台创建具有影响力的业务解决方案。DevExpress WinForms能完美构建流畅、美观且易于使用的应用程序&#xff0c;无论是Office风格的界面&#xff0c;还是分析处理大批量的业务数据&#xff0c;它都能轻松胜…

WinFrom真入门(1)——Windows窗体应用概念

窗体的基本结构 用Winform开发的桌面程序&#xff0c;是在Windows操作系统上运行的&#xff0c;这个不用多说。窗体&#xff08;Form&#xff09;的作用‌&#xff1a;窗体是用户交互的容器&#xff0c;承载按钮、文本框等控件&#xff0c;构成应用程序的界面‌。 在Windows操…

scss预处理器对比css的优点以及基本的使用

本文主要在vue中演示&#xff0c;scss的基本使用。安装命令 npm install sass sass-loader --save-dev 变量 SCSS 支持变量&#xff0c;可将常用的值&#xff08;如颜色、字体大小、间距等&#xff09;定义为变量&#xff0c;方便重复使用和统一修改。 <template><…

Postman 如何高效地转换时间戳?

在 Postman 中&#xff0c;时间戳的处理对于 API 请求和响应的调试和测试至关重要&#xff0c;正确处理时间戳可以确保数据的准确性和一致性&#xff0c;而 Moment 库和原生 JS 是两种常见的处理方式。此外&#xff0c;我们还将介绍 Apifox&#xff0c;它提供了更直观、更简便的…

iptables学习记录

一.四表 filter 表&#xff1a; 主要用于控制数据包的过滤&#xff0c;决定数据包是否允许进出及转发 。比如设置规则允许特定 IP 访问服务器的 SSH 端口&#xff08;22 端口&#xff09;&#xff0c;或禁止某些 IP 访问网站端口&#xff08;80 或 443 端口 &#xff09;。可作…

前端自动创建react项目脚手架

步骤&#xff1a;在终端窗口运行如下命令&#xff1a; npm create vitelatest 也可以指定 vite包 版本&#xff0c; 例如&#xff1a; npm create vite4.1.0 npm执行npm install 很慢 还出现证书问题 执行命令行:npm install -g create-vite npm error code UNABLE_TO_GET_IS…

[从零开始学习JAVA ] 了解线程池

前言&#xff1a; 在Java编程中&#xff0c;线程池是一个强大的工具&#xff0c;它能够管理和复用线程&#xff0c;提供高效的并发处理能力。通过线程池&#xff0c;我们可以有效地控制并发线程的数量&#xff0c;并降低线程创建和销毁的开销。本文将引导你深入了解Java中的线程…

Nginx — Nginx处理Web请求机制解析

一、Nginx请求默认页面资源 1、配置文件详解 修改端口号为8080并重启服务&#xff1a; 二、Nginx进程模型 1、nginx常用命令解析 master进程&#xff1a;主进程&#xff08;只有一个&#xff09; worker进程&#xff1a;工作进程&#xff08;可以有多个&#xff0c;默认只有一…

【C++标准IO库】字符串流

目录 一、字符串流概述 1.1 流的概念回顾 1.2 字符串流的定义和作用 二、istringstream 的使用 2.1 基本用法 2.2 常见应用场景 三、ostringstream 的使用 3.1 基本用法 3.2 常见应用场景 四、stringstream 的使用 4.1 基本用法 4.2 常见应用场景 五、字符串流的错…