c 右值引用之轉移建構函式

2021-10-06 07:08:55 字數 2145 閱讀 5785

右值引用是用來支援轉移語義的。轉移語義可以將資源 ( 堆,系統物件等 ) 從乙個物件轉移到另乙個物件,這樣能夠減少不必要的臨時物件的建立、拷貝以及銷毀,能夠大幅度提高 c++ 應用程式的效能。臨時物件的維護 ( 建立和銷毀 ) 對效能有嚴重影響。

這裡有c++之左值引用和右值引用

在現有的 c++ 機制中,我們可以定義拷貝建構函式和賦值函式。要實現轉移語義,需要定義轉移建構函式,還可以定義轉移賦值操作符。對於右值的拷貝和賦值會呼叫轉移建構函式和轉移賦值操作符。如果轉移建構函式和轉移拷貝操作符沒有定義,那麼就遵循現有的機制,拷貝建構函式和賦值操作符會被呼叫。

這裡有關於拷貝建構函式與移動建構函式的push_back()使用c++之emplace_back()與push_back()區別

下面就用示例演示一下,參考c++ 11 左值,右值,左值引用,右值引用,std::move, std::foward

#include

#include

#include

using

namespace std;

class

mystring

public

://建構函式

mystring()

//過載建構函式

mystring

(const

char

* p)

//拷貝建構函式

mystring

(const mystring& str)

//拷貝賦值操作符

mystring&

operator=(

const mystring& str)

std::cout <<

"copy assignment is called! source: "

<< str._data << std::endl;

return

*this;}

//移動建構函式

mystring

(mystring&& str)

//移動賦值運算子

mystring&

operator

=(mystring&& str)

return

*this;}

virtual

~mystring()

};intmain()

只存在拷貝建構函式和拷貝賦值操作符結果(注釋掉移動建構函式和移動賦值操作符)

這個 string 類已經基本滿足我們演示的需要。在 main 函式中,實現了呼叫拷貝建構函式的操作和拷貝賦值操作符的操作。mystring(「hello」) 和 mystring(「world」) 都是臨時物件,也就是右值。雖然它們是臨時的,但程式仍然呼叫了拷貝構造和拷貝賦值,造成了沒有意義的資源申請和釋放的操作。如果能夠直接使用臨時物件已經申請的資源,既能節省資源,有能節省資源申請和釋放的時間。這正是定義轉移語義的目的

存在移動建構函式和移動賦值操作符結果

關於轉移建構函式有下面幾點需要對照**注意:

引數(右值)的符號必須是右值引用符號,即「&&」。

引數(右值)不可以是常量,因為我們需要修改右值。

引數(右值)的資源鏈結和標記必須修改。否則,右值的析構函式就會釋放資源。轉移到新物件的資源也就無效了。

原因:

我們可以看一下析構函式

virtual

~mystring()

它會delete掉_data的記憶體空間。但是如果呼叫析構函式的時候_data指向的是null,那麼就不會delte任何記憶體空間。

所以如果轉移建構函式或者移動賦值操作符中沒有

str._data =

null

;

雖然呼叫移動建構函式或者移動賦值操作符後,已經獲得了右值的_data的記憶體空間,但是之後右值就被銷毀了,那麼獲得的的那片記憶體也被釋放了,指向的就是乙個不合法的記憶體空間。所以我們就要防止這片空間被銷毀。

C 右值引用與移動構造

c 中提供了兩種引用方式。左值引用與右值引用。其中右值引用是c 11的新標準新增的內容。所謂的右值引用就是必須繫結到右值的引用。在介紹之前,先說明一下c 中的左值和右值的規定。實際上,最早在c語言中就有了左值和右值之分。最初的左值即指在賦值號左邊的變數,右值指在賦值號右邊的變數。隨著c語言的發展和c...

C 11 右值引用和轉移賦值

1.首先認識左值和右值的定義 左值 表示式可以引用到乙個物件,並且這個物件是一塊記憶體空間並可以檢測和儲存,這個表示即是左值。右值最大限度只能被乙個常量引用 const int a 1 規則 臨時變數是右值,且可以改變 t set get t為臨時變數,set 設定新值,get 獲取更改後的值。2....

右值引用 移動建構函式和move

左值和右值判斷 1 可位於賦值號 左側的表示式就是左值 反之,只能位於賦值號右側的表示式就是右值。2 有名稱的 可以獲取到儲存位址的表示式即為左值 反之則是右值。例如 int i 10 10 i 錯誤,10為右值,不能當左值用 int j 20 j i i和j都是左值,但是i可以當右值用 以上面定義...