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

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

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

  • 左值可以修改

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

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

  • 右值不可修改

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

将亡值
  • 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)

 
posted @ 2023-10-09 22:02  云北海  阅读(174)  评论(0编辑  收藏  举报