為了理解他,我們來看這樣一段**:
test.h 檔案:
#pragma once
#include#includeusing namespace std;
class test
;test(const test& t);
test& operator=(const test& t);
test(test&& t)noexcept;
test& operator=(test&& t)noexcept;
~test();
public:
string * str;
};
test.cpp 檔案
#include"test.h"
test::test(const test& t)
test& test::operator=(const test& t)
test::test(test&& t)noexcept
test& test::operator=(test&& t)noexcept
test::~test()
main.cpp 檔案:
#include#include#include"test.h"
using namespace std;
int main()
輸出:
首先說說為什麼會這樣輸出:
1、第乙個 「預設建構函式」 是因為vector vec(1) , 所以事先使用預設建構函式構造了乙個test物件
2、第二個 「預設建構函式」 是因為test t ,使用預設建構函式構造了乙個物件
3、第三個 「移動建構函式」 大多數人會以為是 vec.push_back(std::move(t)) ,push_back 導致物件的移動而輸出的。具體的原因其實是由於重新分配記憶體而導致的,我們的 vector 物件 vec 初始的容量只有 1 ,且裡面已經有乙個物件了,就是vector vec(1)的時候建立的,所以再向vec裡面新增test物件時,就會導致vec重新分配記憶體。由於vec中的物件定義了移動建構函式且是可用的(因為我們將其宣告為了noexcept),所以就會呼叫移動建構函式將vec中原始的那個物件移動到新的記憶體中,從而輸出 「移動建構函式」。
4、第四個 「移動建構函式」 才是因為test 物件 t 被移動到vector 物件 vec 新的空間而輸出的
5、第五個 「析構函式」 是因為重新分配記憶體後,原來的記憶體將被銷毀,所以輸出乙個「析構函式」
6、後面三個 「析構函式」 是因為執行了return 0, 記憶體被釋放,vec 和 t 都被析構,所以輸出三個 「析構函式」
將 test.h 和 test.cpp 檔案中的noexcept 都刪去,輸出的結果變成了:
更改之後的輸出只有第四行的輸出變了,其餘行輸出原因與上面是一樣的
第四行的輸出由 「移動建構函式」 變成了 「拷貝建構函式」 ,原因是:
C 移動建構函式和拷貝建構函式
我們用物件 a初始化物件b 後物件 a我們就不在使用 了,但是物件a的空間還在呀 在析構之前 既然拷貝建構函式,實際上就是把a物件的內容複製乙份到b中,那麼為什麼我們不能直接使用a的空間呢?這樣就避免了新的空間的分配,大大降低了 構造的成本 這就是移動建構函式設計的初衷 拷貝建構函式 中,對於指標,...
c 移動建構函式淺解
本部落格是 c 新經典 王健偉著 的學習筆記,本人是c 初學者,如果有理解錯誤或者理解不足的地方,還請大神能夠指正。c 搞出了std move把左值轉成右值,還搞出移動建構函式,藉此改善效能問題,個人感覺,對我這樣的初學者帶來一定的理解難度。我總結了一下,所謂拷貝建構函式在標準上,是深拷貝,為了改善...
構造析構拷貝函式注意點
1 構造析構拷貝函式都沒有返回值 2 建構函式可以過載 3 析構函式沒有形參 4 手動呼叫析構函式後程式還會再次呼叫,確保呼叫兩次不會影響程式 5 拷貝建構函式的初始化形式 define crt secure no warnings include class test test int x,int...