C 移動建構函式和移動賦值運算子

2021-09-19 10:08:44 字數 1337 閱讀 9868

c++11引入了物件移動而非拷貝的概念,有時候物件發生拷貝後就被銷毀了,這種情況下移動而非拷貝物件會大幅度提公升效能。

移動建構函式類似於拷貝建構函式,不同的是移動建構函式的第乙個引數是乙個右值引用,移動建構函式僅僅移動資料成員,不會分配新的記憶體,所以比拷貝建構函式效能更好。

移動賦值運算子與拷貝賦值運算子的關係和移動建構函式與拷貝建構函式的關係一樣,第乙個引數是乙個右值引用,移動賦值運算子僅僅移動資料成員,不會分配新的記憶體。

在自定義移動賦值運算子時,需要檢查是否存在自賦值,也就是說如果要賦值的物件與自己的位址一樣,則不需要做任何事情。

移動操作必須確保移動後源物件可以被銷毀且銷毀後不會影響新建立的物件,例如如果源物件中有資料成員是指標,則必須置為空,否則在源物件執行析構函式時,會將新建立物件中的指標指向的資源釋放掉。

移動操作還必須保證物件仍然可以安全地為其賦予新值或者可以安全地使用而不依賴其當前值。另一方面,移動操作對移動後源物件中留下的值沒有任何要求,因此我們的程式不應該依賴於移動後源物件中的資料。

與處理拷貝建構函式和拷貝賦值運算子一樣,編譯器也會合成移動建構函式和移動賦值運算子,如果乙個類定義了自己的拷貝建構函式,拷貝賦值運算子或析構函式,編譯器就不會為它合成移動建構函式和移動賦值運算子。

當乙個類沒有定義任何自己版本的拷貝建構函式,拷貝賦值運算子,析構函式,且類的每個非靜態資料成員都可以移動時,編譯器才會為它合成移動建構函式或移動賦值運算子。

定義了乙個移動建構函式或移動賦值運算子的類必須也定義自己的拷貝建構函式和拷貝賦值運算子,否則拷貝建構函式和拷貝賦值運算子會被定義為刪除的。

如果我們使用=default顯式要求編譯器生成合成的移動操作,且編譯器不能移動所有成員,則編譯器會將移動操作定義為刪除的函式。

什麼時候將合成的移動操作定義為刪除的函式遵循與定義刪除的合成拷貝操作類似的原則。

由於移動操作竊取資源,它通常不分配任何資源,因此,移動操作通常不會丟擲任何異常。不丟擲異常的移動建構函式和移動賦值運算子必須標記為noexcept,因為某些標準庫容器除非知道移動操作是無異常的,否則就會進行拷貝。

class person

;person

(const person& person)

person

(const person&& person)

person& operator=

(const person& person)

person& operator=

(person&& person)

return

*this;}}

; person getperson()

intmain

(void

)

移動構造和移動賦值運算子

只是自動幫你呼叫析構。得自己確保寫對這個函式。比如把指標指向清0,讓移後源物件達到乙個安全的可析構狀態。strvec strvec strvec noexcept elements s.elements first free s.first free cap s.cap 容器要保證發生異常時物件沒有...

移動建構函式與移動賦值運算子

定義 新標準的乙個主要的特性是可以移動而不拷貝物件的能力,乙個典型的例子是在分配新記憶體的過程中,將元素從就舊記憶體拷貝到新記憶體中是不必要的 先拷貝元素,在釋放舊記憶體 再者,如果乙個類中含有io類和unique ptr類那麼只能使用移動建構函式 右值引用 定義 右值引用只能繫結到乙個即將銷毀的物...

物件移動,移動建構函式與移動賦值運算子

一 物件移動的概念 把乙個物件的所有權轉交給另乙個物件。完成必要的記憶體移動,斬斷原物件和記憶體的關係。二 移動建構函式 呼叫移動建構函式的情形 函式返回乙個物件時。include include using namespace std classa a a const a temp p new i...