C++11 左右值引用、移动语义

右值引用和移动语义

什么是左值?什么是左值引用?

左值是一个表示数据的表达式(如变量名或解引用的指针),我们可以获取它的地址+可以对它赋值,左值可以出现赋值符号的左边,右值不能出现在赋值符号左边。定义时const修饰符后的左值,不能给他赋值,但是可以取它的地址。左值引用就是给左值的引用,给左值取别名。

int main()
{// 以下的p、b、c、*p都是左值int* p = new int(0);int b = 1;const int c = 2;// 以下几个是对上面左值的左值引用int*& rp = p;int& rb = b;const int& rc = c;int& pvalue = *p;return 0;
}
什么是右值?什么是右值引用?

右值也是一个表示数据的表达式,如:字面常量、表达式返回值,函数返回值(这个不能是左值引用返回)等等,右值可以出现在赋值符号的右边,但是不能出现出现在赋值符号的左边,右值不能取地址。右值引用就是对右值的引用,给右值取别名。右值又分为:纯右值(内置类型表达式的值),将亡值(自定义类型表达式的值)

在这里插入图片描述
需要注意的是右值是不能取地址的,但是给右值取别名后,会导致右值被存储到特定位置,且可以取到该位置的地址,也就是说例如:不能取字面量10的地址,但是rr1引用后,可以对rr1取地址,也可以修改rr1。如果不想rr1被修改,可以用const int&& rr1 去引用,是不是感觉很神奇;
这个了解一下,实际中右值引用的使用场景并不在于此,这个特性也不重要。

在这里插入图片描述

左值引用与右值引用比较
  • 左值引用总结:
  1. 左值引用只能引用左值,不能引用右值。
  2. 但是const左值引用既可引用左值,也可引用右值。
int main()
{// 左值引用只能引用左值,不能引用右值。int a = 10;int& ra1 = a; // ra为a的别名//int& ra2 = 10; // 编译失败,因为10是右值// const左值引用既可引用左值,也可引用右值。const int& ra3 = 10;const int& ra4 = a;return 0;
}
  • 右值引用总结:
  1. 右值引用只能右值,不能引用左值。
  2. 但是右值引用可以move以后的左值。
    在这里插入图片描述
左值引用的意义

左值引用的意义是什么呢?
在之前我们就用过左值引用,左值引用主要是作为函数传参和函数传返回值,在这两个场景下,左值引用可以减少数据拷贝,提高效率。

void func1(string s)
{}void func2(const string& s)
{}const string& func3(const string& s)
{//....return s;
}
string func4(const string& s)
{//....string ret(s);return ret;
}
int main()
{string s1("hello world");func1(s1);//传值传参func2(s1);//传引用传参string s2 = func3(s1);//函数传返回值
//这里用左值引用返回却不行,因为ret是临时变量,出了函数会销毁,无法用左值引用返回func4(s1);return 0;
}

那么右值引用的意义是什么呢?

 1、是补齐左值引用的短板 2、是对于一些右值数据的插入,也能减少拷贝

右值引用的使用场景

我们给string实现上移动构造和移动赋值

移动构造本质是将参数右值的资源窃取过来,占为已有,那么就不用做深拷贝了,所以它叫做移动构造,就是窃取别人的资源来构造自己。移动赋值也一样,也是把将亡值的资源拿过来用。

这里的移动构造和拷贝构造的区别是拷贝构造需要构造一个临时对象,然后把临时对象的资源拿过来自己用,而移动构造这里传过来的值就是一个右值,是一个将亡值,所以就直接把他的资源拿过来自己用,对比拷贝构造,移动构造这里少了一次资源的拷贝。拷贝赋值和移动赋值也差不多类似。

       // 拷贝构造string(const string& s):_str(nullptr){cout << "string(const string& s) -- 拷贝构造-深拷贝" << endl;string tmp(s._str);swap(tmp);}// 拷贝赋值string& operator=(const string& s){cout << "string& operator=(string s) -- 拷贝赋值-深拷贝" << endl;string tmp(s);swap(tmp);return *this;}// 移动构造string(string&& s):_str(nullptr), _size(0), _capacity(0){cout << "string(string&& s) -- 移动构造" << endl;swap(s);}// 移动赋值string& operator=(string&& s){cout << "string& operator=(string&& s) -- 移动赋值" << endl;swap(s);return *this;}

在这里插入图片描述


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

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

相关文章

智汇云舟副总裁陈虹旭受邀出席2024昆山工业元宇宙创新论坛

近日&#xff0c;由昆山市工业和信息化局、昆山经济技术开发区科技局指导&#xff0c;中国电子商会元宇宙专委会主办的2024昆山工业元宇宙创新论坛圆满举行。来自西北工业大学、中国电信股份有限公司昆山分公司、中国电信天翼云公司等单位的一百余位专家和企业领导齐聚一堂&…

【Golang】IEEE754标准二进制字符串转为浮点类型

IEEE754介绍 IEEE 754是一种标准&#xff0c;用于表示和执行浮点数运算的方法。在这个标准中&#xff0c;单精度浮点数使用32位二进制表示&#xff0c;分为三个部分&#xff1a;符号位、指数位和尾数位。 符号位(s)用一个位来表示数的正负&#xff0c;0表示正数&#xff0c;1表…

【信息安全】深度分析邮件安全及钓鱼攻击防范

本博文共计3100余字&#xff0c;预计需阅读20分钟 【邮件安全建设】 一、前言 邮件系统作为企业办公网络架构中重要的组成部分&#xff0c;同时也是业务高频使用的办公应用&#xff0c;一旦出现安全问题&#xff0c;业务将会被严重干扰甚至中断&#xff0c;本篇博客通过攻守两…

腾讯云的域名使用阿里云服务器配置

因为近期云服务器到期了&#xff0c;之前的域名已经完成了备案不想轻易回收。于是就换了个厂商&#xff0c;从腾讯云换到了阿里云。但是因为两个厂商不互通。我又不想把域名转入到阿里云。所以就开启了配置之路&#xff0c;一路磕磕绊绊。给大家整理一份顺序&#xff0c;一步到…

Qt6安装教程

由于QT在5.14版本后不再有离线安装版本&#xff0c;均需要通过在线安装 1.下载exe安装包 打开Open Source Development | Open Source License | Qt&#xff0c;往下拉&#xff0c;找到红框所示的按钮 点进去后点击Download即可 2 安装 下载完成后可得到qt-unified-windows…

vue3基础: 组件注册

组件注册 一个 Vue 组件在使用前需要先被“注册”&#xff0c;这样 Vue 才能在渲染模板时找到其对应的实现。组件注册有两种方式&#xff1a;全局注册和局部注册。 全局注册 我们可以使用 Vue 应用实例的.component()方法&#xff0c;让组件在当前 Vue 应用中全局可用。 im…

[情商-11]:人际交流的心理架构与需求层次模型

目录 前言&#xff1a; 一、心理架构 1.1 个体生理层 1.2 个体心理层 1.3 点对点人际交流层 1.4 社会网络层 1.5 社会价值层 二、人的需求层次模型 2.1 需求&#xff08;欲望&#xff09;层次模型 2.2 基因与人需求之间的关系 2.3 个体生理需求 2.4 个体的心理需求…

平衡小车——调试协议

学习目标 熟悉协议的定义掌握协议生成掌握协议解析熟悉消息队列处理协议熟悉消息队列处理业务学习内容 协议的定义 帧头 命令位 数据长度 数据位 校验位 帧尾 字节数 1 1 1 n 1 1 默认值 0x7a 待定 待定 待定 待定

部署Tomcat

Tomcat简介 名称由来&#xff1a;Tomcat最初是由 Sun的软件构架师詹姆斯邓肯戴维森开发的&#xff0c;后来他帮助将其变 为开源项目&#xff0c;并由Sun贡献给Apache软件基金会&#xff0c;由于大部分开源项目OReilly都会出一本相关的 书&#xff0c;并且将其封面设计成某个动物…

Pandas实战100例 | 案例 16: 字符串操作 - 分割和转换

案例 16: 字符串操作 - 分割和转换 知识点讲解 Pandas 提供了丰富的字符串操作功能&#xff0c;这些功能很大程度上类似于 Python 原生的字符串方法。你可以对 DataFrame 或 Series 中的字符串进行分割、转换、替换等操作。这些操作在处理文本数据时非常有用。 字符串分割: …

计算机毕业设计 基于Java的综合小区管理系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…

力扣labuladong一刷day56天二叉堆实现优先级队列

力扣labuladong一刷day56天二叉堆实现优先级队列 一、二叉堆实现优先级队列 二叉堆就是大顶堆或者小顶堆&#xff0c;底层结构采用数组&#xff0c;从索引1开始&#xff0c;i2是左孩子&#xff0c;i21是右孩子&#xff0c;i/2是父节点。 二叉堆一般有三个操作&#xff1a; 获…

力扣207. 课程表

深度优先搜索 思路&#xff1a; 课程看作节点&#xff0c;依赖关系看作是有向边&#xff0c;整体是一个有向图&#xff1b;要学完所有课程&#xff0c;则需要有向图中不存在相互依赖&#xff0c;即不存在环&#xff1b;依次遍历课程&#xff0c;如果课程状态依赖未解决&#x…

“一键转换PNG至BMP:轻松批量处理,高效优化图片管理“

在数字世界中&#xff0c;图片格式的转换是日常工作中不可或缺的一部分。你是否经常遇到需要将PNG格式的图片转换为BMP格式的需求&#xff1f;是否在处理大量图片时&#xff0c;希望能够实现一键批量转换&#xff0c;提高工作效率&#xff1f; 首先&#xff0c;我们进入首助编…

嵌入式培训机构四个月实训课程笔记(完整版)-Linux网络编程第一天-socket编程练习(物联技术666)

点赞+关注,功德无量。更多配套资料,欢迎私信。 网盘链接:https://pan.baidu.com/s/1NIrDmbm8EtFkB1G8s7E3Sg?pwd=qsoh 提取码:qsoh 1、建立一个服务器和一个客户端,二个之间通信 //--------------------服务器 #include <stdio.h> #include <stdlib.h> #inc…

Dell 机架式服务器 - 高级定制

Dell 机架式服务器 - 高级定制 1. Dell Technologies2.1. Servers & Storage (服务器及存储) -> Servers2.2. Rack Servers (机架式服务器)2.3. Shop2.4. PowerEdge Rack Servers (PowerEdge 机架式服务器)2.5. PowerEdge R760 Rack Server (PowerEdge R760 机架式服务器…

本地通过代码安装禅道系统,解决nginx“504 Gateway Time-out”错误

第一步:下载源码 在官网下载代码包: 下载地址:源码包下载我下载的是PHP7.0版&#xff0c;大家下载随自己喜好下载第二步&#xff1a;安装 安装环境:php(7.0)mysql(8.0)nginx(1.21.1) 由于我在本地安装了BT宝塔面板,所以我以宝塔面板安装演示为例: 创建成功后去 C:\Windows\Syst…

Vue插件

项目功能插件 1、vue-router {path: /,name: home,// 路由的重定向redirect: /home }{// 一级路由, 在根组件中被渲染, 替换根组件的<router-view/>标签path: /one-view,name: one,component: () > import(./views/OneView.vue) }{// 多级路由, 在根组件中被渲染, 替…

【DDR】基于Verilog的DDR控制器的简单实现(一)——初始化

在FPGA中&#xff0c;大规模数据的存储常常会用到DDR。为了方便用户使用&#xff0c;Xilinx提供了DDR MIG IP核&#xff0c;用户能够通过AXI接口进行DDR的读写访问&#xff0c;然而MIG内部自动实现了许多环节&#xff0c;不利于用户深入理解DDR的底层逻辑。 本文以美光(Micro…

《剑指 Offer》专项突破版 - 面试题 5 : 单词长度的最大乘积(C++ 实现)

目录 前言 方法一 方法二 前言 题目链接&#xff1a;318. 最大单词长度乘积 - 力扣&#xff08;LeetCode&#xff09; 题目&#xff1a; 输入一个字符串数组 words&#xff0c;请计算不包含相同字符的两个字符串 words[i] 和 words[j] 的长度乘积的最大值。如果所有字符串…