c++11 之 std::move

2020-08-10 16:21:28

參照傳參:

向函數傳遞參數的參照呼叫方法,把參照的地址複製給形式參數。在函數內,該參照用於存取呼叫中要用到的實際參數。這意味着,修改形式參數會影響實際參數。

拷貝建構函式/複製建構函式

int a = b;

Line line1(10);

Line line2 = line1; // 這裏也呼叫了拷貝建構函式

Line line2(line1);

可取地址有名字左值(lvalue)與右值(rvalue)

左值與右值的概念其實在C++0x中就有了。概括的講,凡是能夠取地址的可以稱之爲左值,反之稱之爲右值,C++中並沒有對左值和右值給出明確的定義,從其解決手段來看類似上面的定義,當然我們還可以定義爲:有名字的物件爲左值,沒有名字的物件爲右值。

參考:https://www.cnblogs.com/happenlee/p/9337776.html

在C++之中的變數只有左值與右值兩種:其中凡是可以取地址的變數就是左值,而沒有名字的臨時變數,字面量就是右值」。 正是因爲這兩種變數分別位於=的左右兩側,所以被命名爲左值與右值。int c =a+b;a+b返回值是右值不可以取地址,&c可以,c作爲變數可以存在=的左側,而稱之爲左值,而a+b作爲字面量或中間結果,沒有辦法取得地址,則稱之爲右值。

在C++之中,使用左值去初始化物件或爲物件賦值時,會呼叫拷貝建構函式或賦值建構函式。而使用一個右值來初始化或賦值時,會呼叫移動建構函式或移動賦值運算子來移動資源,從而避免拷貝,提高效率。 而將亡值可以理解爲通過移動構造其他變數記憶體空間的方式獲取到的值。在確保其他變數不再被使用、或即將被銷燬時,來延長變數值的生命期。而實際上該右值會馬上被銷燬,所以稱之爲:將亡值

int main()
{
    Time test(10,25,12);
    Time test2(test);
    return 0;
}
int main()
{
    Time test(10,25,12);
    Time test2(move(test));
    return 0;
}

 試利用move函數將test強行轉化爲將亡值,來避免記憶體重新分配的過程。但是之後我們也無法再存取test物件的內容了,因爲都在移動建構函式之中置爲了空指針

i++ // 左值
++i // 右值
i[10][]陣列取值返回左值
*i指針取值操作符返回左值
「hello world」字串字面量返回左值
可以標準庫中新增的模板類is_lvalue_reference來判斷表達式是否爲左值,is_rvalue_reference來判斷是否爲右值。
  cout << is_lvalue_reference<decltype(i[10])>::value << endl;
  cout << is_rvalue_reference<decltype(i[10])>::value << endl;

在C++11中,標準庫在<utility>中提供了一個有用的函數std::move,std::move並不能移動任何東西,它唯一的功能是將一個左值強制轉化爲右值參照,繼而可以通過右值參照使用該值,以用於移動語意。從實現上講,std::move基本等同於一個型別轉換:static_cast<T&&>(lvalue);

那我需要怎麼把unique_str傳遞給另外一個unique_str.

禁止拷貝和賦值(底層實現拷貝建構函式和複製建構函式 = delete),可以使用std::move()、unique_ptr.reset(...) 轉移物件指針控制權。