左值引用和右值引用、move函數

左值是可以放在賦值號左邊可以被賦值的值;左值必須要在內存中有實體;右值當在賦值號右邊取出值賦給其他變量的值;右值可以在內存也可以在CPU寄存器。一個對象被用作右值時,使用的是它的內容(值),被當作左值時,使用的是它的地址。

左值

左值:既可以放在等號左側,也可以放在等號右側的變量。例如下面的例子:

int a = 1;

int& b = a

上面的變量a既可以放在等號的左側也可以放在等號的右側,所以她是左值。

右值

右值:只可以放在等號右側的變量。例如下面的例子:

int a = 1;
int b = a + 2;
int& c = a + 2; //error
a+2 = 3; // error

這裏的a+2只能放在等好的右側,所以a+2是右值。

爲什麼a+2只能放在等號右側呢?原因在於a+2會產生一個臨時變量,b=a+2實際上是先算出a+2的結果存儲到臨時變量然後賦值給b,並銷燬這個臨時變量。如果將a+2放到等好的左側,那麼將產生無意義的結果。

綜合上面的左值和右值的概念我們可以得到“左值持久,右值短暫”的概念。左值持久存在,右值將在運算結束後銷燬。

引用

  • 引用是C++語法做的優化,引用的本質還是靠指針來實現的。引用相當於變量的別名。
  • 引用可以改變指針的指向,還可以改變指針所指向的值。
  • 引用的基本規則:聲明引用的時候必須初始化,且一旦綁定,不可把引用綁定到其他對象;即引用必須初始化,不能對引用重定義;
  • 對引用的一切操作,就相當於對原對象的操作。

左值引用

左值引用的基本語法:type &引用名 = 左值表達式;

右值引用

必須綁定到右值,一個將要銷燬的對象

右值引用的基本語法type &&引用名 = 右值表達式;

右值引用在企業開發人員在代碼優化方面會經常用到;

右值引用的“&&”中間不可以有空格。

右值引用的一個重要性質和作用就是隻能綁定到一個將要銷燬的對象,因此我們可以將右值引用的資源移動到另一個對象中

move

std::move 會無條件將自己的參數轉換爲右值。在對象拷貝的時候,在運行時,它們不會產生一行代碼, 可以減少資源創建和釋放。

淺析C++11右值引用和move語義https://www.k2zone.cn/?p=1880

我們通常見到的引用(int &a=b;)可以稱之爲左值引用,而右值引用則是int &&a的形式。右值引用的一個重要性質和作用就是只能綁定到一個將要銷燬的對象,因此我們可以將右值引用的資源移動到另一個對象中。

從上面的介紹我們可以總結出,只有右值可以綁定到右值引用上。但是,話不能說的太慢。我們總有辦法能將左值也綁定到右值引用上,我們可以顯式的使用move將一個左值轉換爲對用的右值引用類型。如下:

int a = 1;
int&& b = std::move(a);

此時,a和b的地址是相同的,b將是a的應用。

總結出來move的概念其實很簡單,就一句話:將一個左值轉換爲對應的右值引用類型。

這裏需要注意一點的就是,右值引用的是將要銷燬的對象,使用move調用意味着告訴編譯器我們有一個左值,但想像右值一樣使用,所以調用move後原來的對象除了賦值和銷燬它外不能有其他的操作(書上是這麼說的,但是測試的時候未發現問題)。

string st = "I love xing";
vector<string> vc ;
vc.push_back(move(st));
cout<<vc[0]<<endl;
if(!st.empty()) cout<<st<<endl;

//輸出一行I love xing
//原來的字符串st已經爲空
string st = "I love xing";
vector<string> vc ;
vc.push_back(st);
cout<<vc[0]<<endl;
if(!st.empty()) cout<<st<<endl;

//輸出兩行I love xing

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章