現代C 理解右值引用

2021-10-08 14:17:23 字數 2435 閱讀 7124

右值引用是c++11中新增新的引用型別。

右值引用只不過是一種新的 c++ 語法。

基於右值引用,引申出的 2 種 c++ 程式設計技巧:移動語義和完美**,難以理解。

引入右值引用的主要目的是提高

程式執行效率。有些物件在複製時需要進行深複製(拷貝),深拷貝往往非常耗時。合理使用右值引用可以避免深複製操作。

右值引用通過減少記憶體的重複申請、拷貝和釋放,有效的提高c++程式的效能

。左值是可定址的變數;(有名稱,能獲取其儲存位址的例項物件)

右值是不可定址的字面量,或者表示式求值過程中建立的可定址的無名臨時物件;

無名的臨時變數只能在賦值號的右邊,而不能出現在賦值號左邊。

左值永續性,右值短暫性。

左值的英文簡寫為「lvalue」,右值的英文簡寫為「rvalue」。很多人認為它們分別是「left value」、「right value」 的縮寫,其實不然。

lvalue 是「loactor value」的縮寫,可意為儲存在記憶體中、有明確儲存位址(可定址)的資料,而 rvalue 譯為 "read value",指的是那些可以提供資料值的資料(不一定可以定址,例如儲存於暫存器中的資料)。

例如,語句

a = b + c,

其中,a在等號左邊,有名,可定址,且生命週期持久,稱為左值;

b+c在等號右邊,無名,且在該語句結束後即被銷毀從而結束生命週期,被稱為右值。

判斷某個表示式是左值還是右值,最常用的有以下 2 種方法。

1) 可位於賦值號(=)左側的表示式就是左值;只能在賦值號右側的表示式就是右值。舉個例子:

int a = 15;

15 = a; //錯誤,15 不能為左值

其中,變數 a 就是左值,而字面量 15 是右值。左值也可以當做右值使用,例如:

int b = 20; // b 是左值

a = b; // a、b 都是左值,只不過將 b 當做右值使用

2) 有名稱的、可以獲取到儲存位址的表示式為左值;反之是右值。

a 和 b 是變數名,且通過 &a 和 &b 可以獲得他們的儲存位址,因此 a 和 b 都是左值;而字面量 15、20,它們沒有名稱,也無法獲取其儲存位址(字面量通常儲存在暫存器中),因此 15、20 都是右值。

int &&   rr1 =2;    //正確,字面值常量是右值

int &&   rr2 =rr1;   //錯誤,表示式rr1是左值!

注意: 變數 rr1是左值,我們不能將乙個右值引用直接賦值給另乙個右值引用型別上。

c++98/03 標準中的引用也稱為左值引用。

int n= 10;

int &a = n; //正確

int &b = 10;    //錯誤

如上所示,編譯器允許我們為 左值 n建立引用,但不可以為右值10建立引用。

const int &b = num;

const int &c = 10;

舊標準可以使用常量左值引用操作右值, 但是無法修改右值。

右值引用,可以引用右值,因而稱為「右值引用」。

右值引用可以引用無名的臨時變數

。右值引用可以修改右值

定義右值引用的格式如下:

型別 && 引用名 = 右值表示式;

例如:class a{};

a & rl = a();   //錯誤,無名臨時變數 a() 是右值,因此不能初始化左值引用 r1

a && r2 = a();   //正確,因 r2 是右值引用

&&的由來

volatile,pointer(*),reference(&),rvalue reference(&&)

同左值引用一樣,右值引用也必須   宣告即進行初始化   操作,且只能使用  右值進行初始化,比如:

int num = 10;

//int && a = num;   //右值引用不能被初始化為左值

int && a = 10;

常量左值引用不同的是,右值引用還可以修改右值。例如:

int && a = 10;

a = 50;

cout << a << endl;

程式輸出結果為 50。

c++ 語法上是支援定義常量右值引用的,例如:

const int&&  a = 10;   //編譯器不會報錯

但這種定義並無用處。

一方面,右值引用主要用於移動語義和完美**,其中前者需要有修改右值的許可權;

常量右值引用的作用就是引用乙個不可修改的右值,這項工作完全可以交給常量左值引用完成。

C 右值引用的初步理解

在c 11中,新增了右值引用是對於經常使用stl的人來說非常有意義的事情。初步理解為 move語義對於效能的提公升。std string abc abc為臨時變數,這裡將呼叫move語義 將abc移動到容器中。std vector v std vectorvv vv.pushback 1 dosom...

c 左值 右值 右值引用 左值引用

c 裡一切值必須屬於左值 右值兩者之一。左值 一切變數 包括用const修飾的變數 物件 包括引用都屬於左值 右值 一切字面值 可以是巨集 臨時無名物件 函式返回值 表示式 如a n 說明一下 函式返回值,返回的是某乙個型別的值,並不是返回變數。左值並不是說能放在 左邊的值就是左值 雖然用const...

c 左值 右值 左值引用 右值引用

在c語言中,左值認為是賦值語句的左側,右值認為是賦值語句的右側。在c 中,意義稍有不同。c 中,每乙個表示式會產生乙個左值或者右值,相應的,該表示式也就被稱作 左值表示式 右值表示式 乙個左值表示式的求值結果是乙個物件或者是乙個函式。左值可以當右值使用,而右值不能當左值使用。c prime 中這麼簡...