C++左值右值
阿新 • • 發佈:2021-11-25
定義與區別
左值 (lvalue, locator value) 表示了一個佔據記憶體中某個可識別的位置(也就是一個地址)的物件。即左值指的是可以取地址的變數。
區分表示式的左右值屬性有一個簡便方法:若可對錶達式用 & 符取址,則為左值,否則為右值。左值與右值的根本區別在於能否獲取記憶體地址,而能否賦值不是區分的依據。
const int a = 10; // 'a' 是左值
a = 10; // 但不可以賦值給它!
左值與右值直接的轉換
一般上講,物件之間的運算,物件是以右值的形式參與的。表示陣列、函式和非完整型別的左值是不能轉換為右值的,因為無法對那些型別進行求值。
int a = 1; // a 是左值 int b = 2; // b 是左值 int c = a + b; // a和b自動轉換為右值求和
右值可以通過一些更顯式的方法產生左值。例如,一元解引用操作符 '*'
需要一個右值引數,但返回一個左值結果。
int arr[] = {1, 2};
int* p = &arr[0];
*(p + 1) = 10; // 正確: p + 1 是右值,但 *(p + 1) 是左值
相反地,一元取地址操作符 '&'
需要一個左值引數,返回一個右值:
int var = 10; int* bad_addr = &(var + 1); // 錯誤: 一元 '&' 操作符需要左值引數 int* addr = &var; // 正確: var 是左值 &var = 40; // 錯誤: 賦值操作的左運算元需要是左值
左值引用
C++中可以使用&符定義引用,如果一個左值同時是引用,就稱為“左值引用”。
std::string s;
std::string& sref = s; //sref為左值引用
非const左值引用 不能使用右值對其賦值。但 const左值引用 可以。
【解析】非const引用型別的變數是可以後續對其進行賦值操作的,但是右值是不可獲取記憶體地址。但const左值引用不一樣,因為常量不能被修改,也就不存在上述問題。
std::string& r = std::string(); //錯誤!std::string()產生一個臨時物件,為右值 const std::string& r = std::string(); //可以
因此,我們經常使用const左值引用作為函式的引數型別,可以減少不必要的物件複製。
C++11 右值引用
參考: