C 小細節7 右值引用

2021-10-05 09:35:01 字數 2291 閱讀 5564

04/24/2020

std::move移動操作

知識總結

右值是臨時物件,臨時物件是什麼?

現在多了乙個右值引用,它可以接受臨時物件,並且延長它的生命週期而且還有位址可以獲得。

右值引用指向將要被銷毀的物件,因此,我們可以從繫結到右值引用的物件「」竊取「」狀態。相當於去偷快要銷毀的物件。

例子1:隱式型別轉換

//隱式轉換出現乙個臨時物件

double a =

3.14

;int

& r = a;

//double轉int,這裡會報錯,說右值不能繫結在左值引用上

int&& r1 = a;

//右值引用接受臨時物件3

需要隱式的把a轉換為int型別,用乙個臨時物件接受為3,然後把這個臨時物件繫結給r,所以這裡並沒有繫結a,所以這個型別轉換是錯誤的。但是給r加上const限定符就可以了,因為r不允許做改變,可以繫結臨時物件。

例子2:返回值作為臨時物件

int

returnrval()

int a =

returnrval()

;//發生了拷貝,並且賦值

int& a =

returnrval()

;//錯誤的,臨時物件不能被左值引用

int&& a =

returnrval()

;//正確,臨時物件可以被右值引用

知道完什麼是右值和右值引用,那它有什麼作用呢?

最主要的作用就是減少拷貝消耗,靈活利用臨時物件。

通常來說,賦值運算子左邊是左值,右邊是右值。

int a =4;

//a是左值,4是右值

int b = a*2;

//b為左值,a為右值,因為a拷貝乙份臨時物件4並乘上2,最後再賦值給b;

int& c= a;

//左值引用,把a的繫結給c,無需執行拷貝。

因為物件有拷貝建構函式,所以很容易檢測出拷貝情況。

class

boyboy

(const boy& aboy)

:mname

(new

string

(*aboy.mname)),

age(aboy.age)

boy(boy&& aboy)

:mname

(aboy.mname)

,age

(aboy.age)

boy&

operator

=(boy&& aboy)

string getname()

const

private

: string* mname =

nullptr

;int age =10;

};boy copy

(boy a)

intmain()

由於編譯器預設開啟了返回值優化(rvo/nrvo),所以有可能只列印乙個,可以在編譯的時候加上-fno-elide-constructors選項關閉返回值優化。

這樣就出現了拷貝多次的問題,所以我們加入了移動拷貝建構函式來對臨時物件的使用,減少對拷貝建構函式的使用次數。

當臨時變數出了作用域外,也會呼叫析構函式,析構掉自己mname指向的空間並且會影響到拷貝物件。所以我們需要提前把它指向nullptr;

std::move使左值轉換為對應的右值引用型別,先看乙個例子:

int

&& r1 =

42;、、正確的

int&& r2 = r1;

//錯誤的

int&& r2 = std::

move

(r1)

;

我們不能將右值引用繫結到乙個右值引用型別的變數上,通常變數表示左值,它有位址。

當使用完move, 左值變成右值,但是我們需要知道,除了對r1賦值或銷毀它外,我們將不再使用它。r1就是臨時物件了。

//對區域性變數進行移動操作

vector res;

for(

int i=

0;i<

1000

;i++

)

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

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

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

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

C 左值 右值 左值引用 右值引用

就變數而言,對於一些變數,我們只會讀取並使用它們的值,而不會改變他們的值 唯讀 對於其餘的變數,我們既會讀取它們的值,有的時候還會改變它們的值 讀寫 這是很常見的。在c 中,前一種變數稱為右值,後一種變數稱為左值,例如 int a 1 a是左值,1是右值稍稍不同的一點是,在c 中,乙個變數是左值還是...