天天看點

左值、左值表達式、左值引用 C++

本文topics

  1. 什麼是左值和右值
  2. 什麼是左值表達式、右值表達式
  3. 引用的分類

之前學習Java的時候隻記得在指派表達式左邊的就是左值,右邊的就是右值。這個說法沒有錯,但今天又在C++中有學習到了關于左右值得概念,在此梳理了一些這些知識點。

左值和右值

左值:左值是一個對象或變量,可以代表着一個固定位址。

int i = 1;//此時,i是個變量,本質和對象一樣,是一塊記憶體區域,代表着一個固定的位址。
           

右值:不能作為左值的都是右值,要麼是一個常量,要麼就是一個使用一次立即被銷毀的臨時變量或臨時對象,右值沒有固定的位址,使用完立即被釋放。

int i = 1 ; //1 是一個右值,沒有固定位址,雖然它也占記憶體,但用完就被立即釋放
           

這裡必須再提醒一下,左值也可以同時擁有右值屬性,但反過來不行。

i =i+5;//這裡右邊的雖然是個左值,但在這裡有右值屬性,可以了解為取出i的值和1相加構成一個值為(x+1)的常數(或者說臨時變量)
           

了解了什麼是左值和右值,那麼哪些地方可以用到呢?

這裡舉介個常見運用左值的運算符的例子

這些運算符都必須運用左值,無法用右值來運算。這裡舉幾個常見的例子

  • 指派運算符的左側必須是左值,這個不用說應該都能了解
  • 取值符号&
int i = 1;
int* ptr = &i;//這裡i必須是個左值
           
  • 容器的下标 [ ]
string s=“daily coding";
cout<<s[1]<<endl;//這裡下标運算符的左邊必須是左值
           
  • ++,- -等。這裡有統一方法可以看一個運算符是不是必須用左值。就是看這個運算符能不能操作字面值,如果不可以,就是左值運算符。
3++;//錯誤,這種直接操作一個字面量顯然不行,是以++是必須運用左值的運算符
           

左值表達式和右值表達式

這個很好了解,一個表達式的求值結果如果是左值,就是左值表達式,否則如果是右值,就是右值表達式

int i = 1;
++i = i+2;
//這裡左邊++i,是傳回一個i的變量,但i的值增加了1,是以是左值表達式
//這裡i+1是一個右值表達式 ,因為它是一個存了3的臨時位址,指派給i++後就被釋放了。

i++ = i + 2;//錯誤,因為i++是一個右值表達式,這裡可以了解為 有一個臨時對象temp=i;i = i+1;然後傳回temp,結果就等于 1  =i+1;是以顯然不行 
           

引用分類

  • 左值引用

    即綁定到左值的引用,必須綁定左值

int i = 1;
int &ref = i;//這裡ref是綁定了i這個左值的引用
int &ref2 = 3;// 3 是右值,無法綁定
           
  • 右值引用

    右值引用的作用是給開發者提供一個想要可以綁定臨時變量的作用,可以通過右值引用符号“&&” 來實作

int &&i=1;//右值引用可直接引用右值,可以了解為想要給 “ 1 ”一個固定的位址,并給與一個變量名i
i = 3;//可以通過i再指派
           
  • Const常量引用,本質上也是左值引用的一種,但差別有二

    一是無法通過這個引用改變引用位址的值,二是它可以間接綁定右值(實際上是綁定了一種左值)

int i = 1;
const int &ref = 1;
i = 10;//錯誤,無法再指派 ,因為ref是一個常量引用

const int &ref2 = 100;//可以引用一個右值,本質上是将100轉換為一個變量,再将ref2引用到這個變量上
           

總結

  1. 左值是一個對象或變量,代表一個固定位址,而沒有固定位址的臨時對象或臨時變量既是右值,不能代表一個固定位址
  2. 左值表達式就是一個值為左值的表達式,右值表達式就是值為右值的表達式
  3. 左值引用隻能引用左值,右值因為隻能引用右值,而const引用就可以同時引用左值和右值(通過臨時變量間接引用右值,實際上是左值引用)

繼續閱讀