C++中讓人忽視的左值和右值

來源:互聯網
上載者:User

標籤:編譯   語言   函數返回   傳回值   生命週期   指標   pre   div   函數參數   

前言

為了瞭解C++11的新特性右值引用,不得不重新認識一下左右值。學習之初,最快的理解,莫過於望文生義了,右值那就是賦值號右邊的值,左值就是賦值號左邊的值。在中學的數學的學習中,我們理解的是,左值等價於等號左邊的值,右值等價於等號右邊的值;當我們繼續學習C語言時,等號=不再叫等號,蓋頭換面叫做賦值號;那麼來到C++我們還能這麼理解嗎?答案是部分否定的。

假如你現在還是這樣理解,那麼請繼續往下......

 

C++中何為左值lvalue和右值rvalue?

左值lvalue:可被引用的資料對象,例如,變數、數組元素、結構成員、引用和解除引用的指標都是左值。在C語言中,左值最初指的是出現在指派陳述式左邊的實體,但這是引入const之前的情況。now,常規變數和const變數都可視為左值,因為可通過地址訪問它們。常規變數屬於可修改的左值,const變數屬於不可修改的左值。左值基本上和以前的認知沒有太大的改變。


右值rvalue:字面常量(用括弧括起來的字串除外,因為它們表示地址)、包含多項的運算式以及傳回值的函數(條件是該函數返回的不是引用)。

 

簡單的區別左值和右值:
右值就是一個臨時變數(後面將詳細的解釋),只有臨時地址空間,左值有其地址空間,換句話說,使用取地址符&對某個值取地址,如果不能得到地址,則是右值!

例如:

int a = 0;

cout << &a << endl; // ok! lvalue

cout << &404;  // error! rvalue

 

對於前面提到的右值的特性:

1) 允許調用成員函數。

2) 只能被 const reference 指向。

3) 右值不能當成左值使用,但左值可以當成右值使用

 

臨時變數

僅當函數參數為const reference時,臨時變數才能與之匹配。

 

什麼時候將建立臨時變數呢?
如果引用參數是const,則編譯器將在下面兩種情況下產生臨時變數:
1. 實參的類型正確,但不是左值
2. 實參的類型不正確,但可以轉換為正確的類型

 

Example:

double cube(const double &ra){        return ra * ra * ra;}double side = 3.0;double* pd = &side;double& rd = side;long edge = 5L;double lens[5] = {2.0, 5.0, 10.0, 12.0};double c1 = cube(side);double c2 = cube(lens[2]);double c3 = cube(rd);double c4 = cube(*pd);double c5 = cube(edge); // ra是臨時變數double c6 = cube(7.0);    // ra是臨時變數double c7 = cube(side + 4.0);    // ra是臨時變數

參數side、lens[2]、rd和*pd都是有名稱的、double類型的資料對象,因此不需要藉助臨時變數,可以為其建立引用。
然而edge雖然有名稱但是類型卻不正確,正好符合產生臨時變數的情況2 “實參的類型不正確,但可以轉換為正確的類型” ,double引用不能指向long。參數7.0和side + 4.0的類型都正確,但是木有名稱,屬於右值。在這些情況下,編譯器都會產生一個臨時匿名變數,並讓ra指向它。這些變數生命週期只在函數調用期間,此後編譯器便會隨意的刪除。

 

為何臨時變數 or 右值 對const引用的限制時合理的呢?

請看下面的例子:

void swapr(int& a, int& b)    // swapr()完成數的交換的功能{    int temp;        temp = a;    a = b;    b = temp;}long a = 5, b = 6;swapr(a, b);

這裡我們使用反證法,假設這個調用是木有錯誤的,那麼這裡的類型不符,因此編譯器將建立兩個int臨時變數,將它們初始化為3和5,然後交換臨時變數的內容,但是這隻是交換了兩個臨時變數的值,a和 b並沒有交換,這與swapr()函數完成的功能是相悖的。


總結來說,如果接受引用參數的函數的意圖是修改作為參數傳遞的變數,則建立臨時變數將阻止這種意圖的實現。解決方案是,禁止建立臨時變數。因此這個調用也是錯誤的。如果函數調用的參數是右值或與相應的const引用參數的類型不符,則C++將建立類型正確的匿名變數,將函數調用的參數的值傳遞給該匿名變數,並讓參數來引用該變數

 

  

 

C++中讓人忽視的左值和右值

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.