C++ 左值于右值的理解
定义与区别
左值 (lvalue, locator value) 表示了一个占据内存中某个可识别的位置(也就是一个地址)的对象。即左值指的是可以取地址的变量。
区分表达式的左右值属性有一个简便方法:若可对表达式用 & 符取址,则为左值,否则为右值。 左值与右值的根本区别在于能否获取内存地址,而能否赋值不是区分的依据。
const int a = 10; // 'a' 是左值
a = 10; // 但不可以赋值给它!
左值与右值直接的转换
一般上讲,对象之间的运算,对象是以右值的形式参与的。表示数组、函数和非完整类型的左值是不能转换为右值的,因为无法对那些类型进行求值。
int a = 1; // a 是左值
int b = 2; // b 是左值
int c = a + b; // a和b自动转换为右值求和
右值可以通过一些更显式的方法产生左值。例如,一元解引用操作符 *
需要一个右值参数,但返回一个左值结果。
int arr[] = {1, 2};
int* p = &arr[0];
*(p + 1) = 10; // 正确: p + 1 是右值,但 *(p + 1) 是左值
相反地,一元取地址操作符 '&' 需要一个左值参数,返回一个右值:
int var = 10;
int* bad_addr = &(var + 1); // 错误: 一元 '&' 操作符需要左值参数
int* addr = &var; // 正确: var 是左值
&var = 40; // 错误: 赋值操作的左操作数需要是左值
左值引用
C++中可以使用&符定义引用,如果一个左值同时是引用,就称为“左值引用”。
std::string s;
std::string& sref = s; //sref为左值引用
非const左值引用 不能使用右值对其赋值。但 const左值引用 可以。
【解析】非const引用类型的变量是可以后续对其进行赋值操作的,但是右值是不可获取内存地址。但const左值引用不一样,因为常量不能被修改,也就不存在上述问题。
std::string& r = std::string(); //错误!std::string()产生一个临时对象,为右值
const std::string& r = std::string(); //可以
因此,我们经常使用const左值引用作为函数的参数类型,可以减少不必要的对象复制。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!