理解lvalue和rvalue

今天看C++模板的資料,裏面說到lvalue,rvalue的問題,這個問題之前也看到過,也查過相關資料,可是沒有考慮得很深,只知道rvalue不能取地址,不能賦值等等一些規則。今天則忽然有了更深層次的理解(也能夠說是頓悟,耗時不過幾秒鐘),記錄下來。函數

下面是我對這兩個單詞字面的意思的猜想:this

  • lvalue估計來源於left value。 在賦值語句中lvalue = rvalue;位置處於左邊。就是能夠修改的值。
  • rvalue估計來源於right value。處於賦值語句右邊,是隻讀的不可修改的值。

接下來是我所悟到內容的詳細分析spa

  • lvalue是能夠賦值的,說明它是一個變量,它在內存中必定存在,必定有地址。因此&lvalue是有效的,能取到在內存中的地址。

    訪問lvalue必定會致使CPU訪問存儲器(相對較慢的操做)。.net

    lvalue的例子:指針

    [cpp]  view plain copy
     
    1. int a;  
    2. a = 10; // a是lvalue。  
    3. int* p = &a; // &a是rvalue。  
    4. &a = 0; //錯誤,&a不是lvalue,由於a的地址一旦分配好了,就不能改變了。  
  • rvalue是不能夠賦值的,它不是一個變量,在內存中沒有存在,沒有地址。它要麼是存在於CPU的寄存器中,要麼是存在於指令中(當即數)。因此只要對rvalue取地址,那麼就必定是錯誤的(編譯器會抱怨的)。對象

    訪問rvalue不會致使CPU訪問存儲器(對當即數和寄存器的訪問很快)。blog

    rvalue的例子:ip

    [cpp]  view plain copy
     
    1. int a;  
    2. a = 10; // 10是rvalue,它沒有地址,&10就是錯誤的表達式。從彙編語言的角度來看,10是直接存在於MOV指令中的當即數。  
    3. 10 = a; // 錯誤,10是rvalue,不可賦值。  
    4. //函數返回值屬於rvalue,由於返回值一般用CPU寄存器傳遞,沒有地址。  
    5. int foo()  
    6. {  
    7.     return 0;  
    8. }  
    9. int b = foo(); //沒問題,函數返回值是rvalue。  
    10. int* p = &foo(); //錯誤,rvalue沒有地址。  
    11. void bar(int& i)  
    12. {  
    13. }  
    14. bar(foo()); //錯誤,bar函數參數須要的是lvalue。  
  • 函數的返回值是rvalue,對於返回int, char 等這樣最基本的類型,是經過CPU寄存器返回的,所以返回值沒有地址是能夠理解的。可是若是函數返回的是一個用戶自定義類型的對象,確定不可能經過寄存器來返回這個對象值的(寄存器大小數量都有限,對象的大小能夠很是大),那到底是怎樣返回對象的呢?

     

    [cpp]  view plain copy
     
    1. class UDT  
    2. {  
    3.   int data[100];  
    4. public:  
    5.   UDT()  
    6.   {  
    7.     printf("construct/n");  
    8.   }  
    9.   BBB& operator = (BBB& )  
    10.   {  
    11.     printf("operator =/n");  
    12.     return *this;  
    13.   }  
    14. };  
    15. UDT foo()  
    16. {  
    17.   return UDT();  
    18. }  
    19. void main()  
    20. {  
    21.   UDT obj = foo();  
    22. }  
    23. //輸出:  
    24. construct  

     

    帶着疑問,我查了查vc編譯出來的代碼,原來obj這個局部變量的地址被壓入了堆棧,foo函數內部以堆棧上的obj地址做爲this指針調用了UDT的構造函數。噢,難怪執行UDT obj = foo();這個語句只有調用了一次構造函數,而沒有調用operator =,這都是由於函數返回值必須是rvalue這個規則所帶來的好處,若是返回值是一個lvalue,那麼這個語句必定會調用operator = 運算符。內存

 

文章來自:http://blog.csdn.net/rogerhe/article/details/6410993get

相關文章
相關標籤/搜索