未呼叫C 11 移動構造函數,首選預設建構子
在某些情況下,可能不會呼叫C 11 移動構造函數,有利於相反,使用預設建構函數。為了理解為什麼,讓我們來看一個例子。
考慮下面的類別:
<code class="cpp">class X { public: explicit X (char* c) { cout << "ctor" << endl; init(c); }; X (X& lv) { cout << "copy" << endl; init(lv.c_); }; X (X&& rv) { cout << "move" << endl; c_ = rv.c_; rv.c_ = nullptr; }; const char* c() { return c_; }; private: void init(char *c) { c_ = new char[strlen(c)+1]; strcpy(c_, c); }; char* c_; };</code>
使用這個類,我們可以建立以下物件:
<code class="cpp">int main() { X x("test"); cout << x.c() << endl; X y(x); cout << y.c() << endl; X z( X("test") ); cout << z.c() << endl; return 0; }</code>
預期輸出為:
ctor test copy test ctor <-- Why not move? test
但是,我們觀察到最後一行沒有呼叫移動構造函數。相反,使用預設構造函數。為了解釋這一點,我們需要了解複製省略。
複製省略是C 11標準在某些條件下允許的最佳化技術。它允許編譯器直接在目標對像中建構臨時對象,從而避免複製/移動構造函數和析構函數的開銷。
在此範例中,從臨時「test」建立的 X 物件被省略到 z 中。這意味著不會呼叫複製/移動建構函數,而是直接將物件建構到 z 中。
當滿足所有這些條件時,編譯器可能會執行複製省略:
在我們的如果滿足這些條件,就會發生複製省略,導致使用預設建構函式而不是移動建構函式。要明確呼叫移動建構函數,您可以使用 std::move,如下所示:
<code class="cpp">X z( std::move(X("test")) );</code>
以上是為什麼從臨時物件建立物件時不呼叫 C 11 移動建構函式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!