C++笔记 将亡值 左右值(基础)
在 C 基础进阶中左值lvalue、右值rvalue和将亡值xvalue是理解变量存储、内存管理、移动语义的核心概念。很多新手会被这几个概念绕晕其实它们的区分逻辑非常清晰本文用最通俗的方式讲透三者的定义、区别和用法。一、先搞懂左值 和 右值C 中所有的表达式都有值类别最基础的分类就是左值和右值。1. 左值lvalue定义可以放在赋值号左边有名字、有内存地址、可以被修改的值。简单记忆能取地址、有名字的就是左值。左值核心特征持久存在在内存中有固定存储不会用完就销毁可寻址能用取到内存地址有名字变量名、对象名都是左值可修改非 const 左值可以被赋值左值示例int a 10; // a是左值有名字能a取地址 a 20; // 左值可以放在左边赋值 int ref a; // 左值可以初始化左值引用 const int b 30; // b是const左值有地址不可修改2. 纯右值prvalue定义只能放在赋值号右边没有名字、没有固定内存地址、用完即销毁的值。简单记忆临时字面量、临时计算结果都是纯右值。纯右值核心特征临时存在执行完当前语句就销毁不持久存储不可寻址不能用取地址无名字只是一个临时值没有变量名不能放在左边赋值纯右值示例int a 10; // 10、20、30 都是纯右值 a 20; int b a 30; // a30的计算结果是纯右值 // 错误示例纯右值不能放在左边 // 10 a; 编译报错 // (a30); 编译报错不能取地址二、进阶概念将亡值xvalue这是 C11 引入的新概念全称eXpiring Value即将消亡的值。1. 将亡值是什么定义本质是临时值但可以被 “移动”是左值和纯右值的中间态。简单记忆马上要被销毁但还能被利用的临时值。2. 将亡值的来源将亡值只有两种场景使用std::move转换后的左值返回右值引用的函数调用结果3. 将亡值核心特征即将销毁生命周期马上结束原本会被释放资源可被移动可以把它的内存、资源 “偷” 过来避免拷贝不可取地址和纯右值一样没有固定持久地址将亡值示例#include utility // std::move 头文件 int a 100; // std::move(a) 把左值a转换成将亡值 int rref std::move(a);这里std::move(a)就是将亡值它原本是左值a标记为 “即将消亡”后续可以直接移动a的资源而不是拷贝。三、三者核心区别一张表看懂表格类别有无名字能否取地址生命周期核心用途左值lvalue有能持久变量、对象、赋值左边纯右值prvalue无不能临时字面量、临时计算结果将亡值xvalue无不能即将销毁移动语义、资源转移一句话总结区分规则有名字、能取地址 → 左值临时字面量 / 计算结果 → 纯右值std::move/ 右值引用返回 → 将亡值四、关键应用为什么要学将亡值C11 之前只有左右值会造成大量不必要的内存拷贝而将亡值是移动语义的基础能大幅提升程序性能。举个例子// 拷贝数据慢把临时字符串复制一份 string s1 hello world; // 移动数据快直接偷走临时字符串的资源不拷贝 string s2 std::move(s1);hello world是纯右值std::move(s1)是将亡值编译器会自动调用移动构造 / 移动赋值避免拷贝开销。五、易混点总结避坑指南const 左值有名字、能取地址属于左值只是不能修改右值引用只能绑定纯右值 / 将亡值不能绑定左值将亡值不是左值也不是纯右值是独立类别所有临时对象都是纯右值 / 将亡值生命周期只在当前语句总结左值有名字、能取地址、持久存在是程序中最常用的变量纯右值临时值、无名字、用完即毁比如数字、计算结果将亡值C11 新增即将消亡但可被移动的值是移动语义的核心核心判断能取地址 左值临时值 右值move 标记 将亡值