左值引用與右值引用在移動語義中的使用

2021-10-09 03:59:47 字數 2995 閱讀 1779

本文主要介紹c++中的左值引用和c++11中的新特性右值引用,以及右值引用在移動語義上的應用。

傳統c++使用的是左值引用,使得標誌符關聯到左值。什麼是左值呢?左值指的是乙個表達資料的表示式,可以應用取位址操作符。常常出現在賦值操作符(=)的左邊,所以被稱為左值。給出如下定義:

左值引用:表示資料的表示式,如變數名或者解除引用的指標。

左值引用:

int n;

//n是左值

int*pt =

newint

;//*pt是左值

const

int b =

101;

//b是左值

int&rn = n;

//rn是左值

int&rt =

*pt;

//rt是左值

const

int& rb = b;

//rb是左值

右值引用:不能使用位址運算子操作的值。通常使用&&來宣告右值引用。其中包括字面常量(c-風格字串除外)、x+y、以及有返回值的函式(返回型別不是引用)。

右值引用

int x =10;

//10是右值

int y =20;

//20是右值

int&&r1 =13;

//r1與13都是右值

int&&r2 = x+y;

//r2與x+y都是右值

double

&& r3 = std::

sqrt

(2.0);

//r3是右值

ps:其中r2關聯到x+y,指的是r2關聯到x+y的結果的值,而不是x+y,如果x或者y發生變化,之後r2是不會發生變化的。

其中,左值轉換為右值,或者右值轉化為左值會有兩種途徑。

方法1:

int&& x =

static_cast

<

int&&

>

(n);

方法2:

#include

four = std::

move

(one)

;//one賦值給four,呼叫了移動賦值運算子

什麼是移動語義?c++11如何使用移動語義?

如果出現如下情況:

vector bigdata;

//含有200000個100000個字元的字串

vector

bigdata_copy

(bigdata)

;//乙個新的物件作為bigdata的複製

vector

allcaps

(const vector

& vs)

//呼叫函式allcaps

vector

bigdata_copy2

(allcaps

(bigdata)

);

會出現什麼問題呢?發現temp這個變數管理著20000000000個字串,vector與string的複製建構函式都會建立2000000000個字元的副本,而且函式也會建立臨時變數作為返回值,結束後銷毀。我們可以發現其中的大多數的複製與銷毀操作時非常多餘的。可以只修改一下這塊記憶體的記錄,將這塊記憶體的記錄賦值給另乙個變數。如上改進的操作就被稱為移動語義。

給出應用移動語義的例子:

#include

using

namespace std;

class

useless

;int useless::ct =0;

useless::

useless()

useless::

useless

(int k):n

(k)useless::

useless

(int k,

char ch):n

(k)showobject()

;}useless::

useless

(const useless& f):n

(f.n)

showobject()

;}useless::

useless

(useless&& f)

noexcept:n

(f.n)

useless::

~useless()

useless useless::

operator+(

const useless& f)

const

void useless::

showobject()

const

void useless::

showdata()

const

intmain()

return0;

}

單獨拿出上述例子中的移動建構函式:

useless::

useless

(useless&& f)

noexcept:n

(f.n)

ps:其中需要注意的是,將物件f的pc賦值給this的pc時,需要將f.pc置為fullptr。因為如果不將f.pc指向fullptr,則f與this物件銷毀的時候,會釋放兩次記憶體,發生錯誤。

在c++11中一般會宣告移動複製建構函式與移動賦值運算子。也可以單獨宣告移動函式。

useless::

useless

(useless&& f)

noexcept:n

(f.n)

useless& useless::

operator

=(useless&& f):n

(f.n)

編譯器會根據引數的型別自動識別輸入的是左值還是右值,呼叫相應的建構函式或者賦值操作符函式。

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

2015 06 01 15 07 404人閱讀收藏 舉報 c 11 5 一 c 中的左值和右值 誤區 左值位於等號左邊,右值位於等號右邊。c 11中的定義 左值表示式表示的是乙個物件的身份 在記憶體中的位置 而右值表示式表示的是物件的值 內容 左值和右值都是針對表示式而言的,左值是持久的,右值是短暫...

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

1 左值和右值的概念 左值是可以放在賦值號左邊可以被賦值的值 左值必須要在記憶體中有實體 右值當在賦值號右邊取出值賦給其他變數的值 右值可以在記憶體也可以在cpu暫存器。乙個物件被用作右值時,使用的是它的內容 值 被當作左值時,使用的是它的位址。2 引用 引用是c 語法做的優化,引用的本質還是靠指標...

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

1 左值和右值的概念 左值是可以放在賦值號左邊可以被賦值的值 左值必須要在記憶體中有實體 右值當在賦值號右邊取出值賦給其他變數的值 右值可以在記憶體也可以在cpu暫存器。乙個物件被用作右值時,使用的是它的內容 值 被當作左值時,使用的是它的位址。2 引用 引用是c 語法做的優化,引用的本質還是靠指標...