其實沒有特意的想去研究研究C++的左值與右值,但是學習小組在研究引用的時候,發現右值引用這個大坑,而右值引用又是C++11才提出的,看了看,還是總結下
一、左值與右值的定義
在不同的C++標準裡,對左值和右值的定義是有所不同的。
C++03版:
①對於一個運算式,其不是左值就是右值;
②左值是對象(指標,對象執行個體)或者函數(比如返回引用的函數,這裡有一點很重要只有聲明沒有初始化的就不能成為左值,比如char* p;初始化為空白*p不是左值,因為*p不是對象)。一些右值也是對象(另外一些右值是宏定義的常量、整形字面量、字串字面量、浮點數字面量等);
③一些內建的操作符和函數調用會產生左值。E的指標類型,(E* p = new E;那麼E調用dereference operator *後,)*E是左值運算式。再比如函數調用int& f()也產生左值,調用f()就是左值運算式
④調用傳回值不為引用的函數得到的是對象是右值,使用者自訂的操作符是普通函數,這些函數是否返回左值,參數是否需要左值是由函數的形參和傳回值決定;
⑤轉換(包括explicit類型轉換,強制轉換等)自臨時變數但是結果為非引用的運算式是右值;
⑥當左值出現在需要右值的地方,左值會轉化為右值;
⑦右值需要完整的類定義或者是void類型,另外,左值可以是非完整定義的類型;
⑧為了修改對象必需使用左值。當然也有一種特例,右值對象通過調用自己的成員函數來修改自身
可以看到,在C++03標準中,並沒有對左值和右值進行一個非常明顯的定義,只是說明了運算式不是左值就是右值,函數返回引用的是左值運算式,而返回非引用的是右值運算式,還有一系列判斷其到底是左值還是右值的方法。
那麼,到底什麼才是左值和右值的標準定義呢?我們來看看最新的C++11標準中的對左值和右值的定義:
C++11版:
1、比較通俗的說話:
左值和右值都是針對錶達式而言的,左值是指運算式結束後依然存在的持久對象,右值是指運算式結束時就不再存在的臨時對象。
區分左值與右值的便捷方法是:看能不能對錶達式取地址,如果能,則為左值,否則為右值。
2、C++11對LValue和RValue的界定:
所謂“值”,都是針對錶達式而言的,為C++11標準中對錶達式的分類:
1)lvalue仍然是傳統意義上的左值;
2)xvalue(eXpiring value)臨終值,按照字面的理解,這個一個即將消亡的值。
實際上,它是某些涉及到右值引用的運算式的值,引用C++11用的原話為:An xvalue is the result of certain kinds of expressions involving rvalue references。
例如:調用一個傳回型別為右值引用的函數的傳回值就是xvalue。
3)prvalue指代一個臨時對象、一個臨時對象的子物件或者一個沒有分配給任何對象的值。prvalue即老標準中的rvalue。
例如:一個函數的傳回值是平常類型,其傳回值是rvalue。例如int foo();沒有分配給任何對象的值。如5.3,true。
4)glvalue(generalized value)被稱為廣義的左值,包括傳統的左值和xvalue。
5)rvalue(right value)被稱為廣義的右值,因為除了傳統意義上的右值,還包括xvalue。
6)lvalue和prvalue分別跟傳統意義上的左值和右值概念是一致的,只是增加了xvalue這樣一個概念。
那麼 ,這個xvalue到底是什麼定義呢?
從字面上去理解:An xvalue is the result of certain kinds of expressions involving rvalue references,即某些涉及到右值引用的運算式的值。關於右值引用,敬請參考下一篇部落格。