在 C++ 11之后,值的类别有三种:左值(lvalue)、纯右值(prvalue)、将亡值(xvalue)。
- 左值 {#title-0} ================
在C++中,左值(lvalue)是指表达式结束后仍然存在的持久性对象或函数。左值可以是变量、数组元素、结构体成员、引用等,它们在内存中有对应的地址。左值具有以下特点:
-
持久性: 左值表示的对象在表达式结束后仍然存在,并且可以被进一步操作或修改。
-
可寻址性: 左值具有内存地址,因此可以被取地址操作符
&
获取其地址。 -
可以赋值: 左值可以作为赋值语句的目标,因为它们表示的是可修改的数据对象。
-
生命周期: 左值的生命周期通常由其作用域和存储类型决定,比如局部变量的生命周期在其所在的作用域结束时结束,而静态变量的生命周期则是整个程序的运行期间。
-
纯右值 {#title-1} =================
在C++中,纯右值(prvalue,pure rvalue)是指表达式,它的值不会被绑定到任何特定的对象或持久性的存储位置。纯右值通常是临时生成的结果,例如常量、临时对象或函数返回的临时值。
纯右值的特点包括:
-
临时性: 纯右值通常是临时性的结果,不会持久存在于程序中,它们的生命周期通常局限于当前表达式的执行范围内。
-
不可修改性: 纯右值通常是不可修改的,因为它们通常是常量或临时对象。试图修改纯右值通常会导致编译错误。
-
不可寻址性: 纯右值不具有内存地址,因此无法对其进行取地址操作。
-
将亡值 {#title-2} =================
在C++中,将亡值(xvalue,expiring value)是一种特殊类型的右值,表示它的值即将被移动或转移,因此它的资源即将被释放或传递给另一个对象。将亡值的特点包括:
- 资源移动或传递: 将亡值表示的对象即将释放其资源或转移其资源所有权给另一个对象。通常,将亡值在赋值给接受右值引用的函数参数时会触发移动语义,避免不必要的拷贝操作。
- 可修改性: 将亡值通常是可修改的,因为它们通常表示的是临时性的结果或资源,可以被修改或转移其值。
- 可寻址性: 将亡值通常具有内存地址,因此可以被取地址操作符
&
获取其地址。但在大多数情况下,将亡值被视为右值,因此不应该进行地址获取操作。 - 临时性: 将亡值通常是临时性的结果,它们的生命周期可能在表达式结束时结束,或者在被传递给其他函数后结束。
为什么称作将亡值?下面是我个人的一点理解。
将亡值是一个广义的术语,用来描述表达式的值即将被移动或转移的情况。这种情况下,无论是左值还是右值,都可以被称为将亡值。
例如:临时对象可以是将亡值,因为它们通常是右值,并且在移动语义中被移动。同时,对于左值对象,如果使用 std::move
或其他方式将其转换为右值引用,并且在移动语义中被移动,那么该左值也可以被称为将亡值。
因此,将亡值可以是左值,也可以是右值。它们的共同特点是,在表达式中它们的值即将被移动或转移。