c++11之左值引用和右值引用

D_Guco發表於2017-03-19

  c++11中增加了右值引用和move語義來避免一些不必要的構造和copy操作,以此來提升程式的執行效率。首先說左值和右值,他們絕不是簡單的等號左邊和右邊的區別,總結來說:

  1 .左值可以定址,而右值不可以。

  2 .左值可以被賦值,右值不可以被賦值,可以用來給左值賦值。

  3 左值可變,右值不可變(僅對基礎型別適用,使用者自定義型別右值引用可以通過成員函式改變)。

  例:int a = 1;左值a可以被尋值,右值1不可以 ,左值a可以被賦值,1不可以,a可變1不可變,int a = b + c,同理a左值,b+c右值。最後c++11中還有一個將亡值的概念,是c++11中新增的跟右值引用相關的表示式,這樣的表示式通常是將要被移動的物件。其實標準庫中有三個函式幫我們判斷引用,左值引用和右值引用: std::is_rvalue_reference<class _Tp>::value,std::is_lvalue_reference<<class _Tp>>::value,std::is_reference<class _Tp>::value

  左值引用就是對左值的引用型別,用T & a來表示,右值引用是對右值的引用型別,用T &&a來表示,左值引用和右值引用同為引用,他們在宣告的同時必須被初始化。他們的初始化繫結有一定的規則和限制,例如一個非常量左值引用不能繫結一個常量左值。具體規則如下:

  

    這裡我們可以看到常量左值引用是可以繫結右值的,其實這在c98中已經存在,只是我們平時沒有留意這個細節而已,例如const int&a = 1等,那麼他和const int a = 1,有什麼不同呢,從語法上講後者的右值在表達時結束後就銷燬了,而前者不會。這就是我們儘量用const 引用代替值傳遞做函式引數的原因,它在某種程度上可以提高效率。

   那麼右值引用有什麼用呢?看一個例子。T&& a = ReturnValue(); 當我們呼叫一個返回一個右值的函式時,當函式返回後,函式返回的右值生命週期也就結束了,但是當我們通過一個右值引用來接收時,該右值有重新獲生命,只要我們的右值引用a存在,該右值也同時存在,這又有什麼用呢,當我們使用T a = ReturnValue();這樣的方式來接收時,會多一次物件的析構和構造,首先用函式返回值構造b,然後函式返回值生命期結束析構。而右值引用則不會,因為右值引用直接繫結了函式返回的右值。

   總結生面兩段話,左值引用和右值引用座位函式引數都能避免物件的拷貝和構造,但是我們通過右值引用改變一個右值時是沒有意義的,而我們通過左值引用改變一個左值是有意義的。

相關文章