首頁  >  文章  >  後端開發  >  為什麼從臨時物件建立物件時不呼叫 C 11 移動建構函式?

為什麼從臨時物件建立物件時不呼叫 C 11 移動建構函式?

Patricia Arquette
Patricia Arquette原創
2024-11-04 19:17:02216瀏覽

Why isn't the C  11 Move Constructor Called When Creating an Object from a Temporary Object?

未呼叫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 中。

當滿足所有這些條件時,編譯器可能會執行複製省略:

  • 該物件是尚未綁定到引用的臨時物件。
  • 該物件被複製/移動到相同 cv-unqualified 類型的物件。

在我們的如果滿足這些條件,就會發生複製省略,導致使用預設建構函式而不是移動建構函式。要明確呼叫移動建構函數,您可以使用 std::move,如下所示:

<code class="cpp">X z( std::move(X("test")) );</code>

以上是為什麼從臨時物件建立物件時不呼叫 C 11 移動建構函式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn