首页 > 其他分享 >左值、右值及其引用的区别

左值、右值及其引用的区别

时间:2023-10-09 22:12:13浏览次数:40  
标签:右值 左值 运算符 引用 表达式 赋值

左值、右值及其引用的区别

概念
左值
  • 左值既可以出现在等号左边,也能出现在等号右边

  • 左值可以修改

  • 左值是可寻址的变量,具有持久性

纯右值
  • 右值只能出现在等号右边

  • 右值不可修改

  • 右值一般是不可寻址的常量,具有临时性

将亡值
  • C++11新增的与右值引用相关的表达式

  • 常用来完成移动构造或移动赋值的特殊任务,扮演着“将亡”的角色

  • 将亡值定义了这样一种行为:具名的临时值、同时又能够被move。

 

示例
左值示例
  • 变量名、函数名以及数据成员名

  • 返回左值引用的函数调用

  • 由赋值运算符或复合赋值运算符连接的表达式,如(a=b, a-=b等)

  • 解引用表达式*ptr

  • 前置自增和自减表达式(++a, ++b)

  • 成员访问(点)运算符的结果

  • 由指针访问成员( -> )运算符的结果

  • 下标运算符的结果([])

  • 字符串字面值("abc")

纯右值示例
  • 字面值(字符串字面值除外),例如1,'a', true等

  • 返回值为非引用的函数调用或操作符重载,例如:str.substr(1, 2), str1 + str2, or it++

  • 后置自增和自减表达式(a++, a--)

  • 算术表达式

  • 逻辑表达式

  • 比较表达式

  • lambda表达式

将亡值示例
  • 返回右值引用的函数返回值,如static_cast<T&&>(t)

  • 转换为右值引用的转换函数的返回值,如std::move(t)

 

引用
左值引用
  • 只能引用左值

  • 通过&运算符声明

右值引用
  • 只能引用右值

  • 通过&&运算符声明

 

C++11的右值引用:

  • 右值引用具有移动语义,可以通过std::move函数将资源的所有权(如动态分配的内存)从一个对象转移到另一个对象,避免了不必要的拷贝和内存分配。

  • 右值引用还使得实现“完美转发”成为可能,也就是将传入的参数原样传递给其他函数,避免了多次拷贝。

 

 

文心一言版解释

左值引用和右值引用是C++中两种重要的概念,它们的区别和意义如下:

  1. 左值引用和右值引用的区别:

    • 基本概念:左值是可以放在赋值号左边,可以被赋值的值,它必须有内存实体;而右值是当在赋值号右边取出值赋给其他变量的值,它可以在内存也可以在CPU寄存器。

    • 操作方式:左值引用是用来改变指针的指向,还可以改变指针所指向的值;右值引用可以用来给左值赋值。

  2. 右值引用的意义:

    • 提高效率:通过避免不必要的对象拷贝,节省运算存储资源,提高程序的执行效率。

    • 简化操作:使得泛型编程更为简洁明确,便于操作。

 

ChatGPT版解释
  1. 区别:

  • 左值引用(lvalue reference):通过&符号来声明,只能引用左值(具有内存地址的表达式或变量),可以修改左值。

  • 右值引用(rvalue reference):通过&&符号来声明,只能引用右值(临时或即将销毁的值),可以修改右值。

  1. 右值引用的意义:

  • 资源移动:右值引用可以通过std::move函数,将一个对象的资源所有权从一个对象转移到另一个对象,避免了不必要的内存拷贝和分配。

  • 完美转发:右值引用允许我们实现所谓的“完美转发”,即将传入的参数原样传递给其他函数,避免了多次拷贝。

  • 优化性能:右值引用可以避免不必要的对象拷贝和析构,提高程序的性能和效率。

 

参考文章:

深入理解左值和右值 - 知乎 (zhihu.com)

 

标签:右值,左值,运算符,引用,表达式,赋值
From: https://www.cnblogs.com/zangwhe/p/17753306.html

相关文章

  • 影刀引用Python模块实现html转为markdown
    比如,我获取了一段html的文本,想要转成markdown格式,可以参考下面用法1.引入一个html2text的包,右键可以看到python包管理器2.插入python代码,转换变量有疑问加站长微信联系(非本文作者)......
  • 左值右值简单理解
    ++i=100;可被g++编译,但是不可被gcc编译;i++=100;不可被g++或gcc编译;左值在内存中具有真实空间,可被覆写。右值可能存在,可能不存在真实空间,不可被人为覆写。inti=0;i=i++;==>i为0;i=++i;==>i为1; ......
  • Maven 引用CDH 5.4 的zookeeper时报错:Could not find artifact javax.jms:jms:jar:1.1
    错误:Couldnotfindartifactjavax.jms:jms:jar:1.1incloudera由于默认5.4.0的包引用了zookeeper3.3.1版本,进而引用了log4j的某个版本,导致的报错,改为如下即可: pom:使用cloudera的源:<repositories><repository><id>cloudera</id><u......
  • 多渠道 打包 - 不同渠道引用不同 dependencies方法
    如下build.gradle文件所示,1.先定义productFlavors渠道channelA和channelB,2.然后通过getTaskNames获取当前编译的渠道,并赋值给变量channel3.dependencies中判断当前channel依赖不同的mudule或者jar--------------------build.gradle文件defchannel=""gradle.startParamet......
  • Java之引用传递
    引用传递分析类本身就属于引用数据类型,既然是引用数据类型,就会牵扯到内存的引用传递。引用传递的本质:同一块堆内存空间可以被不同的栈内存所指向,也可以变更指向。引用传递案例先看一个应用传递的例子:classPerson{ Stringname;intage;publicvoidtell(){......
  • java 中都有哪些引用类型?
    1)强引用Java中默认声明的就是强引用,比如:Objectobj=newObject();obj=null;只要强引用存在,垃圾回收器将永远不会回收被引用的对象。如果想被回收,可以将对象置为null;(2)软引用(SoftReference)在内存足够的时候,软引用不会被回收,只有在内存不足时,系统才会回收软引用对象,如果......
  • Python Weakref弱引用
    背景在开始讨论弱引用的实现之前,我们先来看看什么是弱引用以及弱引用的作用。在我们平常编写代码的时候我们经常会使用引用,了解一下Python,我们就会知道,当一个对象的引用为0时,才会销毁该对象。那么比如我们现在需要维护这样一个东西:不断向一个多线程程序发送数据,同时引入一个缓......
  • 引用变量传参例题
    publicclassTest{publicstaticvoidmain(String[]args){StringBuffera=newStringBuffer("A");StringBufferb=newStringBuffer("B");operate(a,b);System.out.println(a+""+b);......
  • JAVA入门——方法引用
    把已经有的方法拿过来用,当作函数式接口中抽象方法的方法体引用出必须是函数式接口被引用的方法必须已经存在被引用方法的形参和返回值需要和抽象方法保持一致被引用方法的功能要满足当前要求::双冒号是方法引用符 方法引用的分类引用静态方法:格式类名::静态......
  • 无法引用函数,它是已删除的函数
    E1776无法引用函数"A::A(constA&)"(已隐式声明)--它是已删除的函数:https://blog.csdn.net/Bit_Coders/article/details/117260363>>c++拷贝构造函数(深拷贝,浅拷贝)详解:https://www.gxlsystem.com/bianchengyuyan-416455.html......