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

左值引用与右值引用的区别?右值引用的意义?

左值引用与右值引用的区别?右值引用的意义?

  • 1 区别
    • 1.1 功能差异
      • 1.2 左值引用
      • 1.3 右值引用
        • 1.3.1 实现移动语义
        • 1.3.2 实现完美转发
  • 2 引用的作用
  • 3 区分左值和右值
    • 3.1 左值
    • 3.2 右值

1 区别

左值引用是对左值的引用;右值引用是对右值的引用。

(1)使左值指向右值

const 左值引用能指向右值,局限是不能修改这个值。

注意:使用const不能修改值时,可以使用引用,引用该值并对其进行修改。

(2)使右值指向左值

右值引用通过**std::move(v)**可以将左值转化为右值,此时右值就是将亡值。

(3)声明出来的左值引用或右值引用都是左值

int i=0;//引用是必须初始化
//此时的j引用的是右值'100'
int && j=100; //右值引用  int & k=i;//左值引用

1.1 功能差异

1.2 左值引用

避免对象拷贝。

  • 函数传参
  • 函数返回值

1.3 右值引用

1.3.1 实现移动语义

解决对象赋值的问题,避免资源(堆上)的重新分配。有深拷贝的情况下。

以数据库举例。

以前:与数据库创建连接,不想把连接对象关闭,需要再创建另一个连接,再把连接资源拿过来。

现在:直接把连接对象的资源拿给另一个对象是用,就不用再创建并删除一个与数据库之间的连接对象。

以文件举例。

以前:一个文件描述fd,按照以前的深拷贝需要重新打开一个文件。

现在:直接把该文件资源fd移动到另外一个对象中就可以了。

拷贝赋值构造与拷贝构造:

//拷贝赋值构造 深拷贝(资源的重新分配)
A a1,b1;
a1=b1; //拷贝构造 深拷贝
A a2;
A b2(a2);//当前a2是左值
cout<<"b,p="<<b.p<<endl;//输出结果:b,p=A(const A&)...A b2(std::move(a2));//改为右值
cout<<"b,p="<<b.p<<endl;//输出结果:b,p=A(A&&)...

深拷贝与浅拷贝:

//深拷贝
A(const A&a)//拷贝构造
{//拷贝构造中使用的是const,只能读,不能写,所以不能再拷贝构造中使用移动构造进行资源转移p=new int(10);memcpy(p,a.p,10*sizeof(int));//重新分配内存cout<<"A(const A&):p="<<p<<endl;
}//浅拷贝
A(A&& a) //移动构造
{//直接把a上的资源赋值给自己,并把a中的资源置空this->p=a.p;a.p=nullptr;cout<<"A(A&&)"<<endl;
}

stl中的应用:

list<A> alist;
alist.push_back(A());//当前A()为右值
auto &ele=alist.front();//取出第一个值
cout<<"ele.p="<<ele.p<<endl;//输出结果:ele.p=A(A&&)...

1.3.2 实现完美转发

定义:函数模板可以将自己的参数完美地转发给内部调用的其他函数。

完美指的是不仅能准确地转发参数的值,还能保证转发的参数的左右值属性不变。使用std::forward(v)实现。

//左值
void func(int &n)
{cout<<"left value="<<n<<endl;
}//右值
void func(int &&n)
{cout<<"right value="<<n<<endl;
}//调用函数进行转发//c11以前 
template<template T>
void revoke(T &t)
{//此时的t唯一个具体的值func(t);//只能转发左值,调用的函数为func(int &n)
}//c11以前,如果一定要转发右值
void revoke(const T &t)
{func(t);//但是不能对t进行修改
}/**************分割线***************///c11 完美转发
template<template T>
void revoke(T &&t)//T &&t为万能引用
{func(std::forward<T>(t));
}

万能引用:具有模板参数或者模板推导的叫做万能引用。

1)具有模板参数:

template<typename T>
void  tempFun(T&& t) {}  //模板类型的这种用法 T && 是万能引用最常见的使用场合

2)具有模板推导:

auto&& var2 = var1;  //auto这种需要推断类型的地方

万能引用虽然跟右值引用的形式一样,但右值引用需要是确定的类型,如: int && ref = x;就是右值引用。

借用万能引用的方式接受左右属性的值。使用引用折叠规则实现。

template<template T>
void revoke(T &&t)//T &&t为万能引用
{func(std::forward<T>(t));
}int main()
{int i=10;revoke(10);//右值  万能引用中会转换成int && trevoke(i);//左值 万能引用中会转换成int & treturn 0;
}

引用折叠规则

1)参数为左值或左值引用,T&&将转化为int &

2)参数为右值或右值引用,T&&将转化为int &&
在这里插入图片描述
在这里插入图片描述

注意:万能引用只接收值,void revoke(T &&t)中的t仍然是左值!

std::forward(v):

1)T为左值引用,v将转化为T类型的左值。

2)T为右值引用,v将转化为T类型的右值。

int main()
{int i=10;int &m=i;int &&n=100;//不使用类型强制转换,会直接到调用左值void func(int &n)remoke(m);remoke(n);//使用类型强制转换remoke(static_cast<int&>(m));remoke(static_cast<int&&>(n));return 0;
}

2 引用的作用

(1)别名,没有地址

(2)声明时必须要初始化

(3)通过引用修改变量值

3 区分左值和右值

3.1 左值

可以在等号左边,能够取地址,具名

举例:

1)变量名

2)返回左值引用的函数调用

3)前置自增/自减

int i=0;
++i=10;//++i为左值
cout<<i<<endl;  //输出结果:10

4)赋值运算/复合赋值运算

int i=0;
//赋值运算
(i=9)=100;
cout<<i<<endl;//输出结果:100//复合赋值运算
(i+=10)=1000;
cout<<i<<endl;//输出结果:1000

5)解引用

A *a=new A;
*a=...

6)…

3.2 右值

只能在等号右边,不能取地址,不具名

  • 纯右值

    举例:

    1)字面值

    2)返回非引用类型和函数调用

    3)后置自增/自减

    int a=0;
    i++=100;//error 纯右值不能作为左值
    i++;//正确写法
    

    4)算术表达式:+*/

    5)逻辑表达式:^&|~

    6)比较表达式:><=

    7)…

  • 将亡值:c++11新引入的与右值引用(移动语义)相关的值类型

    定义:将亡值用来触发移动构造或移动赋值构造,并进行资源转移,之后将调用析构函数

相关文章:

左值引用与右值引用的区别?右值引用的意义?

左值引用与右值引用的区别&#xff1f;右值引用的意义&#xff1f; 1 区别1.1 功能差异1.2 左值引用1.3 右值引用1.3.1 实现移动语义1.3.2 实现完美转发 2 引用的作用3 区分左值和右值3.1 左值3.2 右值 1 区别 左值引用是对左值的引用&#xff1b;右值引用是对右值的引用。 &…...

2023年深圳杯数学建模D题基于机理的致伤工具推断

2023年深圳杯数学建模 D题 基于机理的致伤工具推断 原题再现&#xff1a; 致伤工具的推断一直是法医工作中的热点和难点。由于作用位置、作用方式的不同&#xff0c;相同的致伤工具在人体组织上会形成不同的损伤形态&#xff0c;不同的致伤工具也可能形成相同的损伤形态。致伤…...

Vue的router学习

,前端路由的核心是什么呢&#xff1f;改变URL&#xff0c;但是页面不进行整体的刷新。 vue-router是基于路由和组件的  路由用于设定访问路径, 将路径和组件映射起来&#xff1b;  在vue-router的单页面应用中, 页面的路径的改变就是组件的切换&#xff1b; 使用router需要…...

Inpaint Anything: 自动化抹除视频元素

自动化抹除视频元素 不用逐帧抠图&#xff0c;直接SAM Tracking Video Inpainting就能实现自动化抹除奔跑吧idol。 https://github.com/geekyutao/Inpaint-Anything 目录 网站演示参考文献 网站 https://huggingface.co/spaces/InpaintAI/Inpaint-Anything 演示 原理就是&a…...

Flutter 开发者工具 Android Studio 开发Flutter应用

Flutter 开发者工具 在 Android Studio 开发Flutter应用 &#x1f525; Android Studio 版本更新 &#x1f525; Android Studio Check for Update Connection failed ​ 解决方案 如果是运行的是32位的android studio需要在andriod studio的启动目录下找到studio.exe.vmoptio…...

后端byte[]传给前端接收默认变成string字符串

创建时间&#xff1a;2023.7.28 建议&#xff1a;最好直接用字符串&#xff0c;我是没办法要求保密&#xff0c;存取都是字符串&#xff0c;程序里面是byte数组 既然他到前端会转换成字符串那么就是被转码了 那我们反向转码就好了 这是在后端处理&#xff0c;反正前端也是乱…...

UE5 动画蓝图模板(Animation Blueprint Template)

文章目录 前言准备内容创建动画蓝图使用动画蓝图模板示例1示例2总结前言 本文基于虚幻5.2版本介绍制作动画蓝图模板,本教程要求使用虚幻5.0及以上版本。 准备内容 使用第三人称游戏内容包,已添加可忽略。 选择第三人称游戏,添加到项目。 创建动画蓝图 在 Characters 文件…...

Log4j源码解析

Log4j源码解析 主要流程 Logger logger Logger.getLogger(Main.class); 1、通过Logger.getLogger(Class clazz) 或 Logger.getLogger(String name)进入。 2、加载LogManager进jvm, 执行静态代码块执行初始化, 创建出RepositorySelector实例及LoggerRepository实例(Hierarchy…...

Docker 容器访问宿主机服务

docker 网络简介 docker 在安装时会默认创建三个网络&#xff1a;bridge&#xff08;默认网络模式&#xff09;、 none 、host。 host 直接和宿主机共用网络。bridge 网络隔离&#xff0c;通过虚拟网桥&#xff08;一般是 docker0&#xff09;与宿主机通信。none 禁用网络功能…...

Go 发送邮件

要在Go中发送电子邮件&#xff0c;您可以使用第三方库&#xff0c;如 gomail 。以下是一个使用 gomail 发送电子邮件的示例代码&#xff1a; package main import ("fmt""gopkg.in/gomail.v2" ) func main() {// 创建邮件消息m : gomail.NewMessage()m.Se…...

Spring AOP 的概念及其作用

一、什么是 Spring AOP&#xff1f; 在介绍 Spring AOP 之前&#xff0c;首先要了解一下什么是 AOP &#xff1f; AOP &#xff08; Aspect Oriented Programming &#xff09;&#xff1a;面向切面编程&#xff0c;它是一种思想&#xff0c; 它是对某一类事情的集中处 理 。…...

python基础1——环境安装

文章目录 一、Windows安装二、Linux安装三、pycharm安装3.1 软件安装3.2 个性化设置3.3 基本使用3.3.1 定义变量3.3.2 查看数据类型3.3.3 运算符3.3.4 操作符3.3.5 转义符 一、Windows安装 1、下载软件安装包&#xff0c;官网 2、开始安装。 2.查看是否安装成功。 3.安装…...

uniapp 中 的progress加载进度条 的使用,在 页面显示数据加载的进度条,使用户的使用体验效果更好

学习目标&#xff1a; 学习目标如下&#xff1a; 例如&#xff1a; uniapp 中 的progress加载进度条 的使用&#xff0c;在 页面显示数据加载的进度条&#xff0c;使用户的使用体验效果更好 学习内容&#xff1a; 学习内容如下所示&#xff1a; 相关属性的说明 进度条的显…...

【尚硅谷】第01章:随堂复习与企业真题(Java语言概述)

来源&#xff1a;尚硅谷Java零基础全套视频教程(宋红康2023版&#xff0c;java入门自学必备) 基本都是宋老师发的资料里面的内容&#xff0c;只不过补充几个资料里没直接给出答案的问题的答案。 不想安装markdown笔记的app所以干脆在这里发一遍。 第01章&#xff1a;随堂复习…...

MyBatis的SqlSession理解

SqlSession是Mybatis最重要的构建之一&#xff0c;可以认为Mybatis一系列的配置目的是生成类似JDBC生成的Connection对象的statement对象&#xff0c;这样才能与数据库开启“沟通”&#xff0c;通过SqlSession可以实现增删改查&#xff08;当然现在更加推荐是使用Mapper接口形式…...

axios 某个接口使用自己独有的完整地址

可以在axios请求中使用完整的URL&#xff0c;而不使用baseURL&#xff0c; 只需将url字段设置为完整的URL即可 import axios from axios;export function getInfo() {return axios({url: http://192.168.3.15:8086/test/messages,method: post}); }直接在url字段中提供了完整的…...

WEB:Web_python_template_injection

背景知识 python模板注入 ssit 题目 打开题目&#xff0c;发现页面提示&#xff0c;翻译为python模板注入 先测试是否存在注入 可以发现被执行了 先查看所有的子类 payload {{[].__class__.__base__.__subclasses__()}} 利用site.Printer的os模块执行命令 payload {{.__…...

【Android安全】Embedded Trace Microcell模块

ETM: Embedded Trace Macrocell, hardware unit responsible to generate hardware instruction trace. ETM模块用于在硬件层面实现instruction trace&#xff0c;可用于辅助逆向分析。 使用教程&#xff1a; https://mcuoneclipse.com/2016/11/05/tutorial-getting-etm-inst…...

修改内核驱动之后-如何给内核打补丁

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言思路步骤1.进入下面路径2.修改文件calibrate.c3.使用git工具生产补丁文件4.移动补丁文件到自己的Linux的recipem目录下总结前言 本文来学习如何使用YOCTO修改Linux内核驱动之后,如何通过打补…...

【javaSE】 类和对象详解

目录 面向对象的初步认知 什么是面向对象 面向对象与面向过程 类定义和使用 简单认识类 类的定义格式 注意事项 练习定义类 定义一个狗类 定义一个学生类 注意事项 类的实例化 什么是实例化 注意事项 类和对象的说明 this引用 为什么要有this引用 什么是this引…...

【WiFi帧结构】

文章目录 帧结构MAC头部管理帧 帧结构 Wi-Fi的帧分为三部分组成&#xff1a;MAC头部frame bodyFCS&#xff0c;其中MAC是固定格式的&#xff0c;frame body是可变长度。 MAC头部有frame control&#xff0c;duration&#xff0c;address1&#xff0c;address2&#xff0c;addre…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求&#xff0c;由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面&#xff1a; &#x1f3db;️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限&#xff0c;形成层级清晰的管理网络&#xf…...

srs linux

下载编译运行 git clone https:///ossrs/srs.git ./configure --h265on make 编译完成后即可启动SRS # 启动 ./objs/srs -c conf/srs.conf # 查看日志 tail -n 30 -f ./objs/srs.log 开放端口 默认RTMP接收推流端口是1935&#xff0c;SRS管理页面端口是8080&#xff0c;可…...

ArcGIS Pro制作水平横向图例+多级标注

今天介绍下载ArcGIS Pro中如何设置水平横向图例。 之前我们介绍了ArcGIS的横向图例制作&#xff1a;ArcGIS横向、多列图例、顺序重排、符号居中、批量更改图例符号等等&#xff08;ArcGIS出图图例8大技巧&#xff09;&#xff0c;那这次我们看看ArcGIS Pro如何更加快捷的操作。…...

以光量子为例,详解量子获取方式

光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学&#xff08;silicon photonics&#xff09;的光波导&#xff08;optical waveguide&#xff09;芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中&#xff0c;光既是波又是粒子。光子本…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

比较数据迁移后MySQL数据库和OceanBase数据仓库中的表

设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...

认识CMake并使用CMake构建自己的第一个项目

1.CMake的作用和优势 跨平台支持&#xff1a;CMake支持多种操作系统和编译器&#xff0c;使用同一份构建配置可以在不同的环境中使用 简化配置&#xff1a;通过CMakeLists.txt文件&#xff0c;用户可以定义项目结构、依赖项、编译选项等&#xff0c;无需手动编写复杂的构建脚本…...

Matlab实现任意伪彩色图像可视化显示

Matlab实现任意伪彩色图像可视化显示 1、灰度原始图像2、RGB彩色原始图像 在科研研究中&#xff0c;如何展示好看的实验结果图像非常重要&#xff01;&#xff01;&#xff01; 1、灰度原始图像 灰度图像每个像素点只有一个数值&#xff0c;代表该点的​​亮度&#xff08;或…...