剖析 移動建構函式

2022-08-21 20:03:08 字數 1673 閱讀 1503

移動建構函式應用的場景????

答:有時候我們會遇到這樣一種情況,我們用物件a初始化物件b,後物件a我們就不在使用了,但是物件a的空間還在呀(在析構之前),既然拷貝建構函式,實際上就是把a物件的內容複製乙份到b中,那麼為什麼我們不能直接使用a的空間呢?這樣就避免了新的空間的分配,大大降低了構造的成本。這就是移動建構函式設計的初衷。

例子示下:

#include#include

using

namespace

std;

class

string;

ostream& operator

<

class

string

else

cout

<< "

constructor execute...

"<

}string(string &&s)noexcept

~string()

private

:

char*m_data;

};ostream& operator

<

intmain()

執行結果:

解析執行結果:

1、第乙個 「預設建構函式」 是因為vectorvs(1) , 所以事先使用預設建構函式構造了乙個test物件

2、第二個 「預設建構函式」 是因為test t ,使用預設建構函式構造了乙個物件

3、第三個 「移動建構函式」 大多數人會以為是 vec.push_back(std::move(s)) ,push_back 導致物件的移動而輸出的。具體的原因其實是由於重新分配記憶體而導致的,我們的 vector 物件 vs 初始的容量只有 1 ,且裡面已經有乙個物件了,就是vectorvs(1)的時候建立的,所以再向vs裡面新增string物件時,就會導致vs重新分配記憶體。由於vs中的物件定義了移動建構函式且是可用的(因為我們將其宣告為了noexcept),所以就會呼叫移動建構函式將vs中原始的那個物件移動到新的記憶體中,從而輸出 「移動建構函式」。

4、第四個 「移動建構函式」 才是因為string物件 t 被移動到vector 物件 vs 新的空間而輸出的

5、第五個 「析構函式」 是因為重新分配記憶體後,原來的記憶體將被銷毀,所以輸出乙個「析構函式」

6、後面三個 「析構函式」 是因為執行了return 0, 記憶體被釋放,vs 和 s 都被析構,所以輸出三個 「析構函式

注意:

第四行的輸出由 「移動建構函式」 變成了 「拷貝建構函式」 ,原因是:

由於我們的移動建構函式沒有宣告為noexcept,所以我們的移動建構函式就會被認為是可能丟擲異常,所以在重新分配記憶體的過程中,vs物件就會使用拷貝建構函式來「移動」物件(這裡說的移動其實是拷貝,並不是移動),所以就輸出了「拷貝建構函式」。

移動建構函式

移動構造 移動構造是c 11標準中提供的一種新的構造方法。在現實中有很多這樣的例子,我們將錢從乙個賬號轉移到另乙個賬號,將手機 sim卡轉移到另一台手機,將檔案從乙個位置剪下到另乙個位置 移動構造可以減少不必要的複製,帶來效能上的提公升。有些複製構造是必要的,我們確實需要另外乙個副本 而有些複製構造...

移動建構函式

c 11新引入了右值引用和移動語義兩個概念。c 包括c 中所有的表示式和變數要麼是左值,要麼是右值。通俗的左值的定義就是非臨時物件,可以在多條語句中使用的物件。右值是指臨時的物件,它們只在當前的語句有效。在c 11之前,右值是不能被引用的。如int a 1 無法從 int 轉化為 int 我們最多只...

C 剖析 轉換建構函式

參考自 狄泰 c 深度解析 我們知道在標準的資料型別之間是有隱式轉換的,轉換關係如下 這是 c語言和 c 裡的轉換關係,我們這裡主要談論c 總所周知c 相比c語言有了乙個類的概念,類中有建構函式,而當建構函式具有以下特點時會成為轉換建構函式 有且只有乙個引數 引數是基本資料型別 引數不是自身類的型別...