C++ 左值、右值、左值引用和右值引用
1、左值和右值
首先,左值和右值是相對於賦值表達式(=、+=等)而言的。左值是在賦值表達式左邊的,右值是在賦值表達式右邊的。左值表達式可以分為可讀寫的左值和只讀左值。右值是可以出現在賦值表達式右邊的表達式,可以是不占據內存空間的臨時量或字面量,可以是不具有寫入權的空間實體。
int a = 3; const int b = 5; a = b + 2; // a是左值,b+2是右值 b = a + 2; // 錯!b是只讀的左值,無寫入權,不能出現在賦值符號的左邊 (a = 4) += 28; // 錯! a=4是表達式,不能作為左值,28是右值,+=為賦值操作符 34 = a = 2; // 錯!34是字面量,不能作為左值 ++a = 12; // 錯! ++a 是表達式,不能作為左值
2、左值引用(如:int &r)
引用的對象可以作為左值來使用的叫做左值引用,一般所說的引用就是左值引用。
3、右值引用(如:int &&r)
右值引用就必須綁定到右值的引用
int i = 42; int &r = i; // 正確,r引用i int &&rr = i; // 錯誤,不能將一個右值引用綁定到一個左值上 int &r2 = i * 42; // 錯誤,i*42是一個右值 const int &r3 = i * 42; // 正確,可以將一個const的引用綁定到一個右值上 int &&r2 = i * 42; // 正確,將rr2綁定到乘法結果上
4、左值持久,右值短暫
左值有持久的狀態,而右值要么是字面值常量,要么是表達式求值過程中創建的臨時對象。由於右值引用只能綁定到臨時對象,得知
1) 所引用的對象將要被銷毀
2)該對象沒有其他用戶
這兩個特征意味着:使用右值引用的代碼可以自由的接管所引用的對象的資源。
5、變量是左值
變量可以看作只有一個運算對象而沒有運算符的表達式,雖然很少這樣看待對象。類似於其他任何表達式,變量表達式也有左值/右值屬性。變量表達式都是左值,帶來的結果就是,不能將一個右值引用綁定到一個右值引用類型的變量上。
int &&r1 = 42; // 正確,字面值常量是右值 int &&r2 = r1; // 錯誤,表達式r1是左值
int &&&r 等於 int &r。