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

C++11 右值引用與移動語意深度解析:從拷貝優化到 std::move 實現

     編輯:C++ 入門

1. 引入背景:臨時對象拷貝開銷

C++ 歷史上臨時對象產生與拷貝效率低下。編譯器優化(Copy Elision、RVO/NRVO)能消除部分情況,但無法覆蓋如 `swap` 等必須使用臨時變數的場景。C++11 引入右值引用,賦予臨時對象「移動語意」,以淺拷貝代價實現資源轉移。

2. C++03 左值與右值

表達式非左即右。判斷:能取地址(`&expr`)為左值,否則為右值。字面值、臨時對象為右值;具名變數為左值。

3. 右值引用綁定規則

引用類型可綁定對象
非 const 左值引用 (`T&`)非 const 左值
const 左值引用 (`const T&`)所有左值、右值
非 const 右值引用 (`T&&`)非 const 右值
const 右值引用 (`const T&&`)所有右值

函數類型例外:右值引用可綁定函數左值。

4. C++11 表達式分類

  • lvalue:傳統左值。
  • prvalue:純右值(臨時對象、字面值)。
  • xvalue:將亡值(右值引用表達式結果、轉型為 `T&&`)。
  • glvalue = lvalue ∪ xvalue。
  • rvalue = prvalue ∪ xvalue。

具名右值引用為 lvalue,不具名為 xvalue。

5. 移動語意實現

為類別添加移動建構函數與移動指派運算子:


class A {
    char* m_data;
public:
    A(const char* s) { m_data = s ? strcpy(new char[strlen(s)+1], s) : 0; }
    // 拷貝
    A(const A& a) { m_data = a.m_data ? strcpy(new char[strlen(a.m_data)+1], a.m_data) : 0; }
    A& operator=(const A& a) { if(this!=&a){ delete[] m_data; m_data = a.m_data ? strcpy(new char[strlen(a.m_data)+1], a.m_data) : 0; } return *this; }
    // 移動
    A(A&& a) : m_data(a.m_data) { a.m_data = 0; }
    A& operator=(A&& a) { if(this!=&a){ m_data = a.m_data; a.m_data = 0; } return *this; }
    ~A() { delete[] m_data; }
};

移動操作僅轉移指標所有權,置空來源,避免深拷貝 `strcpy`。

6. std::move 實現原理


template 
typename remove_reference::type&& move(T&& t) {
    return static_cast::type&&>(t);
}

利用模板參數推導:實參為左值 `T&` 時,`T` 推導為 `U&`,參數類型變為 `U& &&` 崩潰為 `U&`,返回 `U&&`,達到「左值視為右值」效果。`remove_reference` 剝離引用層。

7. 完整示例與輸出


void swap(A& a, A& b) {
    A tmp(move(a));
    a = move(b);
    b = move(tmp);
}
int main() {
    A a("123"), b("456");
    swap(a, b);
    return 0;
}

輸出:

constructor
constructor
move constructor
move assignment
move assignment
destructor
destructor
destructor

全程無拷貝建構/指派,移動語意生效。

總結

  • 右值引用區分「可移動」對象,賦能移動語意。
  • 移動建構/指派實現資源竊取,O(1) 替代 O(n) 深拷貝。
  • `std::move` 非移動,而是「轉型為右值引用」的強制轉換。
  • 配合完美轉發 (`std::forward`) 可構建高效通用庫設施。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved