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

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

  • 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 && t
    revoke(i);//左值 万能引用中会转换成int & t
    
     return 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新引入的与右值引用(移动语义)相关的值类型

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

04 http连接处理(上)

基础知识&#xff1a;epoll、http报文格式、状态码和有限状态机 代码&#xff1a;对服务端处理http请求的全部流程进行简要介绍&#xff0c;然后结合代码对http类及请求接收进行详细分析。 epoll epoll_create函数 #include <sys/epoll.h> int epoll_create(int size)…

回归预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络多输入单输出回归预测

回归预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络多输入单输出回归预测 目录 回归预测 | MATLAB实现TCN-BiLSTM时间卷积双向长短期记忆神经网络多输入单输出回归预测预测效果基本介绍模型描述程序设计参考资料 预测效果 基本介绍 1.MATLAB实现TCN-BiLSTM时间卷积…

CleanMyMac X4.14.1中文版如何清理 Mac系统?CleanMyMac 真的能断网激活吗?

CleanMyMac X4.14.1中文版如何清理 Mac系统&#xff1f;Mac系统在使用过程中都会产生大量系统垃圾&#xff0c;如不需要的系统语言安装包&#xff0c;视频网站缓存文件&#xff0c;mac软件卸载残留的注册表等。 随着时间推移&#xff0c;mac系统垃圾就会越来越多&#xff0c;电…

美团小图币代挂教程

登陆美团官网获取对应的cookie 美团官网&#xff0c;点击右上角登陆对应账号。登陆成功后使用f12来获取 cookie 此时如果没有任何数据&#xff0c;点击网页刷新。找到如下的网络请求 赋值cookie项的全部内容&#xff0c;此时已经获取到对应账号的cookie 使用cookie登陆代挂…

Web博客项目及jwt的学习

这几天完善了发布博客&#xff0c;完成了收藏博客的功能 博客项目 一共有三种身份&#xff1a; 访客&#xff08;未登录&#xff09;&#xff0c;用户&#xff0c;管理员。 其中管理员拥有的功能最多&#xff0c;其次是用户&#xff0c;然后是访客。 从功能上看&#xff1a…

一文3000字从0到1使用Selenium进行自动化测试

对于很多刚入门的测试新手来说&#xff0c;大家都将自动化测试作为自己职业发展的一个主要阶段。可是&#xff0c;在成为一名合格的自动化测试工程师之前&#xff0c;我们不仅要掌握相应的理论知识&#xff0c;还要进行大量的实践&#xff0c;积累足够的经验&#xff0c;以便快…

7.7 SpringBoot实战 管理员借阅审核列表 --分页和枚举的使用

文章目录 前言一、需求二、定义接口 BookAdminController三、核心实现 BookBorrowService新建 BookBorrowService 接口定义如下&#xff1a;新建 BookBorrowServiceImpl 类&#xff0c;核心实现逻辑&#xff1a;新建 BookBorrowBO 四、图书借阅状态枚举 BookBorrowStatusEnum五…

华为数通HCIA-数通网络基础

基础概念 通信&#xff1a;两个实体之间进行信息交流 数据通信&#xff1a;网络设备之间进行的通信 计算机网络&#xff1a;实现网络设备之间进行数据通信的媒介 园区网络&#xff08;企业网络&#xff09;/私网/内网&#xff1a;用于实现园区内部互通&#xff0c;并且需要部…

better scoll的使用以及注意事项以及左联右

下载better scoll的核心 在你要使用的页面引入 在data里面定义一个对象 然后在createad里面放一个nexttick异步操作。 上面是获取这个left-box节点是父节点 记住里面只能有一个子节点如果循环了 就要再包一个div就是一个子节点 左联右 首先也要获取 右边的 父节点 然后配…

(树) 剑指 Offer 28. 对称的二叉树 ——【Leetcode每日一题】

❓ 剑指 Offer 28. 对称的二叉树 难度&#xff1a;简单 请实现一个函数&#xff0c;用来判断一棵二叉树是不是对称的。如果一棵二叉树和它的镜像一样&#xff0c;那么它是对称的。 例如&#xff0c;二叉树 [1,2,2,3,4,4,3] 是对称的。 1/ \2 2/ \ / \3 4 4 3但是下面这个…

了解Unity编辑器之组件篇Layout(八)

Layout&#xff1a;用于管理和控制UI元素的排列和自动调整一、Aspect Ratio Fitter&#xff1a;用于根据宽高比自动调整UI元素的大小 Aspect Mode&#xff1a;用于定义纵横比适配的行为方式。Aspect Mode属性有以下几种选项&#xff1a; &#xff08;1&#xff09;None&#xf…

安全学习DAY12_信息打点-Web应用信息搜集

信息打点-Web应用 文章目录 信息打点-Web应用业务资产企业查信息的目的 Web应用信息搜集Web网站域名搜集WEB单域名WEB子域名OneForAll&#xff08;子域名收集工具&#xff09; WEB网站架构资产WEB指纹识别资产 常用查询平台汇总查企业信息查备案信息查公众号信息域名注册查询IP…

基于 Docker 的深度学习环境:Windows 篇

本篇文章&#xff0c;我们聊聊如何在 Windows 环境下使用 Docker 作为深度学习环境&#xff0c;以及快速运行 SDXL 1.0 正式版&#xff0c;可能是目前网上比较简单的 Docker、WSL2 配置教程啦。 写在前面 早些时候&#xff0c;写过一篇《基于 Docker 的深度学习环境&#xff…

幅度调制与角度调制

文章目录 前言一、调制简介1、调制定义2、调制目的3、调制的分类 二、幅度调制&#xff08;线性调制&#xff09;1、幅度调制的一般模型2、常规双边带调幅 AM①、AM 信号的产生②、AM 调制器的模型③、AM 波形和频谱④、AM 信号的特点⑤、AM 包络检波⑥、调幅系数 3、抑制载波双…

【用IDEA基于Scala2.12.18开发Spark 3.4.1 项目】

目录 使用IDEA创建Spark项目设置sbt依赖创建Spark 项目结构新建Scala代码 使用IDEA创建Spark项目 打开IDEA后选址新建项目 选址sbt选项 配置JDK debug 解决方案 相关的依赖下载出问题多的话&#xff0c;可以关闭idea&#xff0c;重启再等等即可。 设置sbt依赖 将sbt…

neo4j教程-Cypher操作

Cypher基础操作 Cypher是图形存储数据库Neo4j的查询语言&#xff0c;Cypher是通过模式匹配Neo4j数据库中的节点和关系&#xff0c;从而对数据库Neo4j中的节点和关系进行一系列的相关操作。 下面&#xff0c;通过一张表来介绍一下常用的Neo4j操作命令及相关说明&#xff0c;具…

基于峰谷分时电价引导下的电动汽车充电负荷优化(matlab代码)

目录 1 主要内容 峰谷电价优化 电动汽车充电负荷变化 2 部分代码 3 程序结果 1 主要内容 该程序基本复现《基于峰谷分时电价引导下的电动汽车充电负荷优化》&#xff0c;代码主要做的是基于NSGA-II的电动汽车充电负荷优化&#xff0c;首先&#xff0c;在研究电动汽车用户充…

【VSCode部署模型】导出TensorFlow2.X训练好的模型信息

参考tensorflow2.0 C加载python训练保存的pb模型 经过模型训练及保存&#xff0c;我们得到“OptimalModelDataSet2”文件夹&#xff0c;模型的保存方法(.h5或.pb文件)&#xff0c;参考【Visual Studio Code】c/c部署tensorflow训练的模型 其中“OptimalModelDataSet2”文件夹保…

HDFS中namenode安全模式

HDFS中namenode安全模式 安全模式的现象探究step1step2step3step4 安全模式的概述控制进入时间和离开条件安全模式自动进入离开安全模式手动进入离开 安全模式的现象探究 step1 HDFS集群在停机状态下&#xff0c;使用hdfs -daemon命令逐个进程启动集群&#xff0c;观察现象首…

太猛了,靠“吹牛”过顺丰一面,月薪30K

说在前面 在40岁老架构师尼恩的&#xff08;50&#xff09;读者社群中&#xff0c;经常有小伙伴&#xff0c;需要面试美团、京东、阿里、 百度、头条等大厂。 下面是一个5年小伙伴成功拿到通过了顺丰面试&#xff0c;拿到offer&#xff0c;月薪30K。 现在把面试真题和参考答…
最新文章