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

左值引用右值引用

文章目录

  • 左值和右值
    • 什么是左值什么是右值
    • 左值引用与右值引用的比较
      • 左值引用总结
      • 右值引用的总结:
  • 右值引用使用场景和意义
    • 左值引用的使用场景
    • 左值引用的短板
  • 右值引用和移动语义解决上面的问题
    • 不仅仅有移动构造还有移动赋值
  • 右值引用引用左值及其一些更深入的使用场景分析
  • 完美转发
    • 模板中的&&万能引用

左值和右值

什么是左值什么是右值

首先关于左值和右值我们的第一印象左边的是左值右边的是右值(这里的左右值,指的是等号的左右)
但是实际上我们并不这样区分或者说这样子区分是不太准确的左值是一个表示数据的表达式(比如说变量名和解引用的指针),我们可以获取它的地址+对它赋值,左值可以出现赋值符号的左边也可以出现在赋值符号的右边,而右值不能出现在赋值符号的左边 但是被const定义的左值不能出现在等于号的左边不能给他赋值但是可以取他的地址,因此我们可以通过能否取地址来判断左右值

可以取地址的是左值不可以取地址的是右值

右值可以是一个表达式比如说a+b是一个右值也可以是一个常量比如说10 都是右值。右值引用就是对右值取别名。这里需要注意一个事情常量字符串是属于左值的

左值引用与右值引用的比较

左值引用总结

1.左值引用只能引用左值不能引用右值
2.但是const左值引用可以引用右值。

右值引用的总结:

1.右值引用只能引用右值不能引用左值,
2,但是右值引用可以move以后的右值。

右值引用使用场景和意义

前面我们可以看到左值引用既可以引用左值和又可以引用右值,那为什么要提出右值引用?这里我们需要先从左值引用的短板说起。请看 以下代码这是我自己实现的string

#include"string.h"
clzyf::string func()
{clzyf::string a= "****************";return a;
}
int main()
{clzyf::string b = func();clzyf::string a = b;return 0;
}

请大家看看这里需要拷贝多少次呢?首先如果去掉构造函数的话我们这里的传值返回就需要先拷贝一个临时对象再将临时对象传给b然后在进行销毁,但是我们运行程序的时候会发现这里程序进行了优化那么我们可能会疑惑为什么我们不吧这里定义成引用返回,这里是因为这个函数作用域在接下来是会被销毁的那么这个对象也会被销毁,当将其销毁后其地址也就会释放,那么这里传引用也没用因为这个对象已经被销毁了。
在这里插入图片描述
我们可以发现这里运行程序,也会崩溃,所以这样字是肯定不行的。我们可以总结

左值引用的使用场景

做参数和做返回值都可以提高效率。

左值引用的短板

当函数返回对象是一个局部变量,出了函数作用域就不存在了,就不能使用左值引用返回,
只能传值返回。例如:bit::string to_string(int value)函数中可以看到,这里只能使用传值返回,
传值返回会导致至少1次拷贝构造(如果是一些旧一点的编译器可能是两次拷贝构造)。

右值引用和移动语义解决上面的问题

在string中增加移动构造,移动构造本质是将参数右值的资源窃取过来,占位已有,那么就不
用做深拷贝了,所以它叫做移动构造,就是窃取别人的资源来构造自己。
我们来给大家看一下代码。

string(string&& s):_str(nullptr)
,_size(0),_capacity(0)
{cout << "string(string&& s) -- 移动语义" << endl;swap(s);
}

在将这个代码加入进去后我们就可以发现再运行的时候这里没有调用深拷贝和拷贝构造而是调用了移动构造移动构造没有新开空间拷贝数据所以效率提高了。
这里为什么可以调用移动构造呢?原因是因为内置类型在这里进行拷贝的时候它本身其实是一个将亡值,那么作为一个将亡值它本身是要被销毁掉的,因此它的地址是不可取的,它属于右值那么就会调用右值引用的移动构造,进行一个swap是的他的资源不被释放而是被交换给b而b的资源则有将亡值销毁的时候进行释放代码如下

#include"string.h"
clzyf::string  func()
{clzyf::string a= "****************";return a;
}
int main()
{clzyf::string b;b = func();return 0;
}

不仅仅有移动构造还有移动赋值

string类中增加移动赋值函数,再去调string(1234),不过这次是将string(1234)返回的右值对象赋值给ret1对象,这时调用的是移动构造。
代码入下

clzyf::string to_string(int  s)
{string str;return str;
}
// 移动赋值
string& operator=(string&& s)
{
cout << "string& operator=(string&& s) -- 移动语义" << endl;
swap(s);
return *this;
}
int main()
{clzyf::string ret1;ret1 = clzyf::string(1234);return 0;
}

这里运行后我们可以看到进行了一次移动构造和一次移动赋值我们这里是先用to_string 返回一个右值然后通过这个右值调用移动赋值来给ret1进行赋值

右值引用引用左值及其一些更深入的使用场景分析

按照语法,右值引用只能引用右值,但右值引用一定不能引用左值吗?因为:有些场景下,可能
真的需要用右值去引用左值实现移动语义。当需要用右值引用引用一个左值时,可以通过move
函数将左值转化为右值。C++11中,std::move()函数位于 头文件中,该函数名字具有迷惑性,
它并不搬移任何东西,唯一的功能就是将一个左值强制转化为右值引用,然后实现移动语义。

完美转发

模板中的&&万能引用

void Fun(int &x){ cout << "左值引用" << endl; }
void Fun(const int &x){ cout << "const 左值引用" << endl; }
void Fun(int &&x){ cout << "右值引用" << endl; }
void Fun(const int &&x){ cout << "const 右值引用" << endl; }
// 模板中的&&不代表右值引用,而是万能引用,其既能接收左值又能接收右值。
// 模板的万能引用只是提供了能够接收同时接收左值引用和右值引用的能力,
// 但是引用类型的唯一作用就是限制了接收的类型,后续使用中都退化成了左值,
// 我们希望能够在传递过程中保持它的左值或者右值的属性, 就需要用我们下面学习的完美转发
template<typename T>
void PerfectForward(T&& t)
{Fun(t);
}
int main()
{PerfectForward(10);           // 右值int a;PerfectForward(a);            // 左值PerfectForward(std::move(a)); // 右值const int b = 8;PerfectForward(b);      // const 左值PerfectForward(std::move(b)); // const 右值return 0;
}

万能引用既可以接受左值也可以接受右值这里的原因是因为这里有个方式就是引用折叠他的格式是模板

template<class T>
void func(T&&t)
{
return;
}

此时这个小t就是一个万能引用万能引用当我们传入左值的时候会进行折叠从而接受左值当我们传入右值的时候不需要折叠本身就是右值因此既可以接受左值对象又可以接受右值

相关文章:

左值引用右值引用

文章目录 左值和右值什么是左值什么是右值左值引用与右值引用的比较左值引用总结右值引用的总结&#xff1a; 右值引用使用场景和意义左值引用的使用场景左值引用的短板 右值引用和移动语义解决上面的问题不仅仅有移动构造还有移动赋值 右值引用引用左值及其一些更深入的使用场…...

学习开发一个RISC-V上的操作系统(汪辰老师) — 一次RV32I加法指令的反汇编

前言 &#xff08;1&#xff09;此系列文章是跟着汪辰老师的RISC-V课程所记录的学习笔记。 &#xff08;2&#xff09;该课程相关代码gitee链接&#xff1b; &#xff08;3&#xff09;PLCT实验室实习生长期招聘&#xff1a;招聘信息链接 前置知识 RISC-V 汇编指令编码格式 &a…...

IDEA中点击New没有Java Class

解决办法&#xff1a;右键src&#xff0c;也可以是其他文件名&#xff0c;点击Mark Directory as 点击Sources Root即可...

打造炫酷效果:用Java优雅地制作Excel迷你图

摘要&#xff1a;本文由葡萄城技术团队原创并首发。转载请注明出处&#xff1a;葡萄城官网&#xff0c;葡萄城为开发者提供专业的开发工具、解决方案和服务&#xff0c;赋能开发者。 前言 迷你图是一种简洁而有效的数据可视化方式&#xff0c;常用于展示趋势和变化。它通常由一…...

pycharm设置pyuic和pyrcc

pyuic设置 适合任何虚拟环境&#xff0c;直接用虚拟环境的python解决一切。。。 E:\anaconda3\envs\qt5\python.exe-m PyQt5.uic.pyuic $FileName$ -o $FileNameWithoutExtension$.py$FileDir$pyrcc设置 E:\anaconda3\envs\qt5\python.exe-m PyQt5.pyrcc_main $FileName$ -o…...

OpenCV6-图形绘制

OpenCV6-图形绘制 1.绘制圆形2.绘制直线3.绘制椭圆4.绘制多边形5.文字生成6.demo 1.绘制圆形 void cv::circle(InputOutputArray img, // 需要绘制圆形的图像Point center, // 圆心坐标int radius, // 半径&#xff0c;单位为像素const Scalar& colo…...

kafka消费者程序日志报错Offset commit failed问题研究

生产环境偶尔会遇到kafka消费者程序日志报错的问题 截取主要日志如下&#xff1a; 2023-10-02 19:35:28.554 {trace: d7f97f70dd693e3d} ERROR[Thread-49:137] ConsumerCoordinator$OffsetCommitResponseHandler.handle(812) - [Consumer clientIdconsumer-1, groupIdcid_yin…...

SpringBoot+原生HTML+MySQL开发的电子病历系统源码

电子病历系统源码 电子病历编辑器源码 云端SaaS服务 电子病历系统&#xff0c;采用 “所见即所得、一体化方式”&#xff0c;协助医生和护士准确、标准、快捷实现病历书写、修改、审阅、打印、体温单浏览、医嘱管理等&#xff0c;是提供病历快速简洁化完成的一系列综合型医生病…...

软件测试/测试开发/人工智能丨聊聊AutoGPT那些事儿

点此获取更多相关资料 简介 在 ChatGPT 问世之后&#xff0c;大家很容易就发现其依然具备一些很难解决的问题&#xff0c;比如&#xff1a; Token 超出限制怎么办&#xff1f;&#xff08;目前最新的 GPT4 支持最多8,192 tokens&#xff09;。如何完全自动化&#xff1f;任务…...

KdMapper扩展实现之SOKNO S.R.L(speedfan.sys)

1.背景 KdMapper是一个利用intel的驱动漏洞可以无痕的加载未经签名的驱动&#xff0c;本文是利用其它漏洞&#xff08;参考《【转载】利用签名驱动漏洞加载未签名驱动》&#xff09;做相应的修改以实现类似功能。需要大家对KdMapper的代码有一定了解。 2.驱动信息 驱动名称spee…...

MATLAB算法实战应用案例精讲-【图像处理】计算机视觉

目录 前言 几个高频面试题目 计算机视觉与图像处理、模式识别、机器学习学科之间的关系 计算机视觉和机器人视觉区别与联系...

docker应用的缓存 docker缓存机制

Docker镜像用作Docker执行程序中的主映像。它们是容器的蓝图&#xff0c;提供了有关如何生成容器的说明。在本文中&#xff0c;我将介绍一些经常被忽视的概念&#xff0c;这些概念将有助于优化Docker镜像开发和构建过程。 让我们从Docker构建过程的简短描述开始。这是通过使用…...

借助 ZooKeeper 生成唯一 UUID

ZooKeeper是一个分布式协调服务&#xff0c;它主要用于在分布式系统中管理和协调各种资源。它本身并不提供生成唯一UUID的功能&#xff0c;但你可以借助ZooKeeper来实现生成唯一UUID的机制。 下面是一种基于ZooKeeper的方法来生成唯一UUID的示例&#xff1a; 在ZooKeeper中创建…...

Redis哨兵机制原理

Redis哨兵机制可以保证Redis服务的高可用性。它通过启动一个或多个哨兵进程&#xff0c;监控Redis主服务器是否宕机&#xff0c;如果宕机&#xff0c;哨兵进程会自动将一个从服务器&#xff08;Slave&#xff09;升级为主服务器&#xff08;Master&#xff09;&#xff0c;并通…...

Maven Web应用

目录 创建 Web 应用 构建 Web 应用 部署 Web 应用 测试 Web 应用 本章节我们将学习如何使用版本控制系统 Maven 来管理一个基于 web 的项目&#xff0c;如何创建、构建、部署以及运行一个 web 应用。 创建 Web 应用 我们可以使用 maven-archetype-webapp 插件来创建一个简…...

考古:MFC界面的自适应缩放(代码示例)

MFC窗体的控件的自适应缩放早期VS开发环境是不支持的&#xff0c;后来VS开发环境提供了支持但也简单&#xff0c;或者固定的缩放比例不符合要求。我一向坚持一个理念&#xff1a;“不支持缩放的窗口不是好窗口”&#xff0c;所以需要有一个自定义的缩放处理。机制不复杂&#x…...

计算机网络 | 物理层

计算机网络 | 物理层 计算机网络 | 物理层基本概念数据通信基本知识&#xff08;一&#xff09;一个数据通信流程的例子数据通信相关术语三种通信方式数据传输方式串行传输和并行传输同步传输和异步传输 小结 数据通信基本知识&#xff08;二&#xff09;码元&#xff08;Symbo…...

Centos下编译ffmpeg动态库

文章目录 一、下载ffmpeg安装包二、编译ffmpeg三、安装yasm 一、下载ffmpeg安装包 下载包 wget http://www.ffmpeg.org/releases/ffmpeg-4.4.tar.gz解压 tar -zxvf ffmpeg-4.4.tar.gz二、编译ffmpeg 进入解压的目录 cd ffmpeg-4.4编译动态库 ./configure --enable-shared…...

深度学习:UserWarning: The parameter ‘pretrained‘ is deprecated since 0.13..解决办法

深度学习&#xff1a;UserWarning: The parameter ‘pretrained’ is deprecated since 0.13 and may be removed in the future, please use ‘weights’ instead. 解决办法 1 报错警告&#xff1a; pytorch版本&#xff1a;0.14.1 在利用pytorch中的预训练模型时&#xff0…...

leetcode-279. 完全平方数

1. 题目链接 链接: 题目链接 2. 解答 #include <stdio.h> #include <stdlib.h> #include <stdbool.h>bool issquare(int n) {if (n 1 || n 4) return true;if (n 2 || n 3) return false;for (int i 3; i < n/2; i ) {if (n i*i) return true;}…...

OpCore-Simplify:如何30分钟完成专业级黑苹果配置

OpCore-Simplify&#xff1a;如何30分钟完成专业级黑苹果配置 【免费下载链接】OpCore-Simplify A tool designed to simplify the creation of OpenCore EFI 项目地址: https://gitcode.com/GitHub_Trending/op/OpCore-Simplify 还在为复杂的黑苹果配置而烦恼吗&#x…...

语音钓鱼中转窝点运作机理与全链条防控研究 —— 基于韩国仁川警方案例

摘要 2026 年 5 月 19 日韩国仁川西部警方通报&#xff0c;破获一起以高薪兼职为诱饵招募人员、在住宿场所运营语音钓鱼中转窝点的案件&#xff0c;抓获两名管理人员&#xff0c;查获一次性手机 105 部、冒用他人身份 SIM 卡 356 张、无线路由器 4 台&#xff0c;涉案人员通过远…...

免费开源游戏串流方案Sunshine:5分钟打造家庭游戏共享中心

免费开源游戏串流方案Sunshine&#xff1a;5分钟打造家庭游戏共享中心 【免费下载链接】Sunshine Self-hosted game stream host for Moonlight. 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine 还在为无法在客厅大屏上畅玩书房电脑里的3A大作而烦恼&#…...

2026年初中生赴新加坡留学,费用究竟几何?一文为你揭秘!

在教育全球化的今天&#xff0c;越来越多的家长将目光投向海外&#xff0c;新加坡凭借其优质的教育资源、安全的社会环境和多元的文化氛围&#xff0c;成为众多初中生留学的热门选择。那么&#xff0c;2026年初中生赴新加坡留学的费用到底是多少呢&#xff1f;本文将为你详细揭…...

别再手动算潮流了!用MATLAB+Matpower搞定IEEE标准算例(附完整代码)

电力系统潮流计算实战&#xff1a;MATLABMatpower高效解决方案 在电力系统分析与设计中&#xff0c;潮流计算是最基础却至关重要的环节。传统的手工计算方式不仅耗时费力&#xff0c;而且难以应对复杂网络结构的分析需求。本文将带您探索如何利用MATLAB平台上的Matpower工具包&…...

某供应链企业200GB数据泄露复盘:如果开了透明加密,攻击者拿走的只有乱码

图&#xff1a;供应链企业数据泄露的3条典型路径&#xff08;U盘导出/数据库导出/截图&#xff09;与TDE透明加密的拦截机制事件还原&#xff1a;一次"完美"的内部数据窃取说明&#xff1a;以下事件基于多起真实安全事件综合脱敏处理&#xff0c;技术细节均为真实攻击…...

UNet迁移实战:如何用Labelme标注自己的数据,并快速替换官方数据集进行训练

UNet迁移实战&#xff1a;从Labelme标注到自定义数据集训练全流程指南 当你在GitHub上成功运行了UNet的官方Demo后&#xff0c;下一步自然是想让这个强大的语义分割模型为你自己的项目服务——无论是分析医学影像中的病变区域&#xff0c;还是识别卫星图片中的特定地物。本文将…...

Keil MDK 项目迁移避坑指南:当你的旧工程遇到‘Default Compiler Version 5 is not available’

Keil MDK项目迁移实战&#xff1a;编译器版本冲突的工程级解决方案 当你从同事手中接过一个历史遗留的Keil MDK项目&#xff0c;或从版本控制系统拉取多年前的嵌入式工程时&#xff0c;最令人头疼的莫过于打开工程后迎面而来的编译器报错。其中"Default Compiler Version …...

N_m3u8DL-RE完整教程:跨平台流媒体下载的终极解决方案

N_m3u8DL-RE完整教程&#xff1a;跨平台流媒体下载的终极解决方案 【免费下载链接】N_m3u8DL-RE Cross-Platform, modern and powerful stream downloader for MPD/M3U8/ISM. English/简体中文/繁體中文. 项目地址: https://gitcode.com/GitHub_Trending/nm3/N_m3u8DL-RE …...

告别环境冲突:用Conda+Docker在Win10上丝滑搭建MMDetection双环境(附CUDA 11.1/PyTorch 1.8配置)

深度学习环境工程化实践&#xff1a;Conda与Docker双方案打造MMDetection高效工作流 在Windows系统上搭建深度学习开发环境&#xff0c;就像在雷区跳舞——CUDA版本冲突、Python依赖不兼容、系统环境污染等问题随时可能引爆。以MMDetection为例&#xff0c;这个强大的目标检测工…...