左值、右值及其引用的区别
概念
左值
-
左值既可以出现在等号左边,也能出现在等号右边
-
左值可以修改
-
左值是可寻址的变量,具有持久性
纯右值
-
右值只能出现在等号右边
-
右值不可修改
-
将亡值
-
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++中两种重要的概念,它们的区别和意义如下:
左值引用和右值引用的区别:
基本概念:左值是可以放在赋值号左边,可以被赋值的值,它必须有内存实体;而右值是当在赋值号右边取出值赋给其他变量的值,它可以在内存也可以在CPU寄存器。
操作方式:左值引用是用来改变指针的指向,还可以改变指针所指向的值;右值引用可以用来给左值赋值。
右值引用的意义:
提高效率:通过避免不必要的对象拷贝,节省运算存储资源,提高程序的执行效率。
简化操作:使得泛型编程更为简洁明确,便于操作。
ChatGPT版解释
区别:
左值引用(lvalue reference):通过&符号来声明,只能引用左值(具有内存地址的表达式或变量),可以修改左值。
右值引用(rvalue reference):通过&&符号来声明,只能引用右值(临时或即将销毁的值),可以修改右值。
右值引用的意义:
资源移动:右值引用可以通过std::move函数,将一个对象的资源所有权从一个对象转移到另一个对象,避免了不必要的内存拷贝和分配。
完美转发:右值引用允许我们实现所谓的“完美转发”,即将传入的参数原样传递给其他函数,避免了多次拷贝。
优化性能:右值引用可以避免不必要的对象拷贝和析构,提高程序的性能和效率。
参考文章: