左值右值

在C++中,对值的分类非常重要,因为它决定了你可以对这些值做什么操作。左值(lvalue)和右值(rvalue)是C++中的两种主要的表达式类别,而左值引用和右值引用则是与之对应的引用类型。

左值 (Lvalue)

左值是指那些表达式,它们指向内存中的一个固定位置,这样的表达式可以出现在赋值语句的左侧。它们通常是一个变量、数组的一个元素或者一个对象的一个属性。左值可以取地址,即可以使用&运算符来得到其内存地址。

示例:

1
2
int x = 10; // x是一个左值
x = 20; // x可以在赋值语句的左侧出现

在这个例子中,x是一个左值,因为你可以对它赋值。x具有一个持久的内存地址,可以在程序的多个地方引用和修改。

右值 (Rvalue)

右值是指那些不指向内存中固定位置的表达式。右值通常是临时的,不能取地址,也不能在赋值语句的左侧出现。一个典型的右值是字面量或者一个表达式的结果(例如函数返回的临时对象或者一个算术表达式的结果)。

示例:

1
int y = 10 + 5; // 10 + 5是一个右值

这里的表达式10 + 5就是一个右值,因为它不对应内存中的一个固定位置,而是一个临时计算的结果,它的值可以用来初始化变量y

左值引用 (Lvalue Reference)

左值引用是对左值的引用。在声明中,左值引用由类型后跟一个&符号表示。左值引用可以用来创建一个对象的别名。

示例:

1
2
3
int a = 42;
int& ref = a; // ref是对整数a的左值引用
ref = 10; // 修改ref也会修改a

这里的refa的左值引用,改变ref的值也会改变a的值。

右值引用 (Rvalue Reference)

右值引用是C++11中引入的一种新类型引用,它允许引用右值。在声明中,右值引用由类型后跟一个&&符号表示。右值引用使得可以安全地“移动”资源,而不是复制资源,这是C++11中引入移动语义和完美转发的关键部分。

示例:

1
int&& rref = 10 + 5; // rref是对临时右值的引用

这里的rref是一个右值引用,它引用了10 + 5这个右值表达式的结果。

总结:

  • 左值:可以在赋值语句的左侧,有持续的状态,可以取地址。
  • 右值:临时的,通常不能取地址,不能在赋值语句的左侧。
  • 左值引用:对左值的引用,用&表示。
  • 右值引用:对右值的引用,用&&表示,C++11中新增。