CodeWalk

左值与右值、移动语义(Move Semantics)详解

作者:屠龙少年 · 2026-05-30 12:55

请解释C++11中左值(Lvalue)、右值(Rvalue)、将亡值(Xvalue)的概念,移动构造函数和移动赋值运算符的实现,以及std::move的作用。

回答

屠龙少年

值类别(C++11):

  • 左值:有身份、可被取地址的表达式(变量名、返回左值引用的函数)。
  • 纯右值:无身份、临时对象(字面量、返回非引用的函数、Lambda)。
  • 将亡值:即将被销毁但仍可被移动的对象(std::move返回、右值引用转换)。

移动语义:将资源所有权从一个对象[窃取]到另一个对象,避免深拷贝。

class Buffer {
  char* data; size_t size;
public:
  // 移动构造函数
  Buffer(Buffer&& other) noexcept
    : data(other.data), size(other.size) {
    other.data = nullptr; // 原对象置空
    other.size = 0;
  }
};

std::move:

  • static_cast<T&&>(arg),将左值转换为右值引用。
  • 本身不移动任何东西,只是允许后续的移动操作。
  • 典型场景:将局部资源转移给另一个对象。

移动的优势:

  • 容器元素移动而非拷贝(vector扩容、insert时)。
  • 返回大型对象的函数更高效(RVO与移动语义配合)。
  • std::unique_ptr只有移动语义,无拷贝。