首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C/C++ 進階:左值、右值與值類別深度解析

     編輯:關於C++

引言

C++11 引入了右值引用與移動語義,徹底改變了資源管理方式。要理解 std::move、std::forward 等機制,必須先搞清楚左值與右值的本質。本文依據 C++ 標準草案(N3797)與 cppreference 等權威資料,系統梳理值類別體系。

一、值類別層級關係

C++ 表達式分為兩大基本類別:glvalue(廣義左值)與 rvalue(右值)。其中 glvalue 再細分為 lvalue(左值)與 xvalue(將亡值);rvalue 細分為 prvalue(純右值)與 xvalue。關係圖譜如下:

expression
├── glvalue (has identity)
│   ├── lvalue (cannot be moved from)
│   └── xvalue (can be moved from)
└── rvalue (can be moved from)
    ├── prvalue (no identity)
    └── xvalue (has identity)

二、核心定義

1. 左值

  • 歷史上因可出現在賦值運算符左側而得名。
  • 指代一個持久存在的對象或函數,具有名稱或可取地址。
  • 例子:變量名、解引用指針 *p、返回左值引用的函數調用、前置遞增 ++i。
  • 特徵:有身份,不可被移動。

2. 右值

  • 歷史上因可出現在賦值運算符右側而得名。
  • 臨時對象、字面值、返回非引用類型的函數調用、後置遞增 i++、算術運算結果等。
  • 特徵:可被移動,可能有身份(xvalue)也可能無身份(prvalue)。

3. 將亡值

  • 接近生命週期末尾、即將被移動的對象(如 std::move(x) 的結果)。
  • 特徵:有身份,可被移動。

4. 純右值

  • 無身份的臨時值(如字面值 42、lambda 表達式、算術運算結果)。
  • 特徵:無身份,可被移動。

三、判斷表達式值類別的兩大屬性

  1. has identity:能否通過地址比較確定是否指向同一實體。
  2. can be moved from:能否綁定到移動構造函數或移動賦值運算符。

四、常見表達式分類速查

表達式類別說明
變量名 xlvalue即使類型是右值引用,表達式本身仍是左值
std::move(x)xvalue轉換為右值引用
42, trueprvalue字面值
x + yprvalue算術運算結果
++xlvalue前置遞增返回左值引用
x++prvalue後置遞增返回臨時值
*plvalue解引用指針
a[n] (a 為左值)lvalue下標運算
a[n] (a 為右值)xvalueC++11 起

五、實戰意義

  • 重載決議:右值優先綁定 T&&,左值綁定 T& 或 const T&。
  • 移動語義:將左值轉為 xvalue (std::move) 可觸發移動構造/賦值,避免深拷貝。
  • 完美轉發:結合 std::forward 保持實參值類別。

六、參考資料

  1. cppreference: Value categories
  2. MSDN: Rvalue Reference Declarator: &&
  3. ISO C++ Standard Draft N3797, §3.10
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved