1. 程式人生 > >C++11新特性之右值引用

C++11新特性之右值引用

  • 什麼是左值,什麼是右值?
    An l-value expression refers to an object's identity, whereas a r-value expression refers to an object's value.
    左值標識物件的身份,右值標識物件的值(我把它理解為被物件佔據的一塊記憶體資源)。

  • 常見的左值有“變數名”,常見的右值有“字面量”或者“變數經std::move轉換的結果”。

  • C++11增加了對右值引用的支援,右值引用是幹什麼的呢?

    從字面意思理解,右值引用當然是用來標識一個右值的身份了,通過它可以找到繫結的右值,方便對右值的讀寫。

  • std::move函式的作用是把一個左值轉變成右值返回。

    如果返回的右值被用作了move操作(move constructor / assignment)的引數,那麼原來的左值x所佔有的資源已經被別的物件偷走,後面再對x操作時要明白,x的一部分資源已經不可靠了。

    如果x是stl定義的型別,stl向我們保證x的賦值和析構操作是可以正常執行的,

    如果是我們自定義型別,應該注意,move constructor / assignment操作應該保證被偷走資源的引數物件可以正常被析構。

  • 誰和誰可以繫結到一起?

int i = 10;
// 右值引用-右值
int&& rr = 42;
int&& rr1 = std::move(i);
//const左值引用--右值
const int& c = 42;
//左值引用--左值
int& lr = rr;
//注意:右值引用也是變數,所以rr是左值。
  • 右值引用常見用法

    1.如果把左值引用理解為變數的別名,那麼右值引用就是資源的別名。通過右值引用可以直接操作藏在物件名後面的物件資源。

    string a = "aaa";
    string&& r = std::move(a);
    r = "rrr";
    cout << a << endl;
    /*output:
    rrr
    */

2.作為move constructor 和 move assignment的引數。

    string a("aaa");
    string b(std::move(a));
    cout << "move construct b from a, a:" << a << "\tb:" << b << endl;
    string c("ccc");
    c = std::move(b);
    cout << "move assignment c from b, b:" << b << "\tc:" << c << endl;//可見,string的拷貝賦值裡,對b和c的資源指標做了swap