面試題 什麼是右值引用?右值引用與左值引用的區別

2021-10-10 16:52:19 字數 3240 閱讀 7910

什麼是左值引用呢?

左值引用,就是繫結到左值的引用,通過&來獲得左值引用

那麼,什麼是左值呢?

左值,就是在記憶體有確定儲存位址、有變數名,表示式結束依然存在的值。

左值可以分為兩類:非常量左值和常量左值;同理,右值也可以分為兩類:非常量右值和常量左值。

左值引用舉例說明:

int a=10;

//非常量左值(有確定儲存位址,也有變數名)

const

int a1=10;

//常量左值(有確定儲存位址,也有變數名)

const

int a2=20;

//常量左值(有確定儲存位址,也有變數名)

//非常量左值引用

int&b1=a;

//正確,a是乙個非常量左值,可以被非常量左值引用繫結

int&b2=a1;

//錯誤,a1是乙個常量左值,不可以被非常量左值引用繫結

int&b3=10;

//錯誤,10是乙個非常量右值,不可以被非常量左值引用繫結

int&b4=a1+a2;

//錯誤,(a1+a2)是乙個常量右值,不可以被非常量左值引用繫結

//常量左值引用

const

int&c1=a;

//正確,a是乙個非常量左值,可以被非常量右值引用繫結

const

int&c2=a1;

//正確,a1是乙個常量左值,可以被非常量右值引用繫結

const

int&c3=a+a1;

//正確,(a+a1)是乙個非常量右值,可以被常量右值引用繫結

const

int&c4=a1+a2;

//正確,(a1+a2)是乙個常量右值,可以被非常量右值引用繫結

可以歸納為:非常量左值引用只能繫結到非常量左值上;常量左值引用可以繫結到非常量左值、常量左值、非常量右值、常量右值等所有的值型別。

顧名思義,什麼是右值引用呢?

右值引用,就是繫結到右值的引用,通過&&來獲得右值引用

那麼,什麼又是右值呢?

右值,就是在記憶體沒有確定儲存位址、沒有變數名,表示式結束就會銷毀的值。

右值引用舉例說明:

int a=10;

//非常量左值(有確定儲存位址,也有變數名)

const

int a1=20;

//常量左值(有確定儲存位址,也有變數名)

const

int a2=20;

//常量左值(有確定儲存位址,也有變數名)

//非常量右值引用

int&&b1=a;

//錯誤,a是乙個非常量左值,不可以被非常量右值引用繫結

int&&b2=a1;

//錯誤,a1是乙個常量左值,不可以被非常量右值引用繫結

int&&b3=10;

//正確,10是乙個非常量右值,可以被非常量右值引用繫結

int&&b4=a1+a2;

//錯誤,(a1+a2)是乙個常量右值,不可以被非常量右值引用繫結

//常量右值引用

const

int&&c1=a;

//錯誤,a是乙個非常量左值,不可以被常量右值引用繫結

const

int&&c2=a1;

//錯誤,a1是乙個常量左值,不可以被常量右值引用繫結

const

int&&c3=a+a1;

//正確,(a+a1)是乙個非常量右值,可以被常量右值引用繫結

const

int&&c4=a1+a2;

//正確,(a1+a2)是乙個常量右值,不可以被常量右值引用繫結

可以將右值引用歸納為:非常量右值引用只能繫結到非常量右值上;常量右值引用可以繫結到非常量右值、常量右值上。

從上述可以發現,常量左值引用可以繫結到右值上,但右值引用不能繫結任何型別的左值,若想利用右值引用繫結左值該怎麼辦呢?

c++11中提供了乙個標準庫move函式獲得繫結到左值上的右值引用,即直接呼叫std::move告訴編譯器將左值像對待同型別右值一樣處理,但是被呼叫後的左值將不能再被使用

std::move使用舉例說明:

int a=10;

//非常量左值(有確定儲存位址,也有變數名)

const

int a1=20;

//常量左值(有確定儲存位址,也有變數名)

//非常量右值引用

int&&d1=std::

move

(a);

//正確,將非常量左值a轉換為非常量右值,可以被非常量右值引用繫結

int&&d2=std::

move

(a1)

;//錯誤,將常量左值a1轉換為常量右值,不可以被非常量右值引用繫結

//常量右值引用

const

int&&c1=std::

move

(a);

//正確,將非常量左值a轉換為非常量右值,可以被常量右值引用繫結

const

int&&c2=std::

move

(a1)

;//正確,將常量左值a1轉換為常量右值,可以被常量右值引用繫結

可以發現,編譯器利用std::move將左值強制轉換為相同型別的右值之後,引用情況跟右值是一模一樣的。

(1)左值引用繫結到有確定儲存空間以及變數名的物件上,表示式結束後物件依然存在;右值引用繫結到要求轉換的表示式、字面常量、返回右值的表示式等臨時物件上,賦值表示式結束後就物件就會被銷毀。

(2)左值引用後可以利用別名修改左值物件;右值引用繫結的值不能修改。

(1)替代需要銷毀物件的拷貝,提高效率:某些情況下,需要拷貝乙個物件然後將其銷毀,如:臨時類物件的拷貝就要先將舊記憶體的資源拷貝到新記憶體,然後釋放舊記憶體,引入右值引用後,就可以讓新物件直接使用舊記憶體並且銷毀原物件,這樣就減少了記憶體和運算資源的使用,從而提高了執行效率;

(2)移動含有不能共享資源的類物件:像io、unique_ptr這樣的類包含不能被共享的資源(如:io緩衝、指標),因此,這些類物件不能拷貝但可以移動。這種情況,需要先呼叫std::move將左值強制轉換為右值,再進行右值引用。

右值引用的使用方法可參考部落格:

左值 右值與右值引用

在c語言中,我們常常會提起左值 lvalue 右值 rvalue 這樣的稱呼。而在編譯程式時,編譯器有時也會在錯誤的資訊中包含左值 右值的說法。不過左值 右值通常不是通過乙個嚴謹的定義而為人所知的,大多數時候左右值的定義與判別方法是一體的。乙個典型的判別方法就是,在賦值表示式中,出現在等號左邊的就是...

左值 右值 左值引用 右值引用

2015 06 01 15 07 404人閱讀收藏 舉報 c 11 5 一 c 中的左值和右值 誤區 左值位於等號左邊,右值位於等號右邊。c 11中的定義 左值表示式表示的是乙個物件的身份 在記憶體中的位置 而右值表示式表示的是物件的值 內容 左值和右值都是針對表示式而言的,左值是持久的,右值是短暫...

左值 左值引用 右值 右值引用

1 左值和右值的概念 左值是可以放在賦值號左邊可以被賦值的值 左值必須要在記憶體中有實體 右值當在賦值號右邊取出值賦給其他變數的值 右值可以在記憶體也可以在cpu暫存器。乙個物件被用作右值時,使用的是它的內容 值 被當作左值時,使用的是它的位址。2 引用 引用是c 語法做的優化,引用的本質還是靠指標...