什麼是左值引用呢?
左值引用,就是繫結到左值的引用,通過&來獲得左值引用。
那麼,什麼是左值呢?
左值,就是在記憶體有確定儲存位址、有變數名,表示式結束依然存在的值。
左值可以分為兩類:非常量左值和常量左值;同理,右值也可以分為兩類:非常量右值和常量左值。
左值引用舉例說明:
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 語法做的優化,引用的本質還是靠指標...