首頁  >  文章  >  後端開發  >  在 C 中按值傳回命名物件時,隱式移動規則如何運作?

在 C 中按值傳回命名物件時,隱式移動規則如何運作?

DDD
DDD原創
2024-11-04 06:20:02175瀏覽

How does the Implicit Move Rule work when returning a named object by value in C  ?

按值傳回類別的命名物件和隱式移動規則

當從函數以值傳回類別的物件時,隱式移動規則來自進入遊戲。此規則控制編譯器在建構臨時物件來保存傳回值時的行為。

範例1:

考慮以下程式碼片段:

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(const test& z) {
        printf("test(const test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>

輸出:

test()
test(test&& s)

在此範例中,函數Some_thing 傳回測試類別的命名對象,建構使用預設建構函數。由於編譯器可以透過 NRVO(命名回傳值最佳化)消除副本,因此我們看到預設建構子 test() 的輸出,後面跟著隱式移動建構子 test(test&& s)。

範例2:

現在,讓我們修改Some_thing 函數以使用複製建構子

<code class="cpp">class test {
public:
    test(int y) {
        printf("test(int y)\n");
    }
    test() {
        printf("test()\n");
    }
    test(test& z) {
        printf("test(test&z)\n");
    }
    test(test&& s)noexcept {
        printf("test(test&& s)\n");  // Deleted this constructor
    }
    test& operator=(test e) {
        printf("test& operator=(test e)\n");
        return *this;
    }
};

test Some_thing() {
    test i;
    return i;
}

int main()
{
    Some_thing();
    return 0;
}</code>

輸出:

test()
test(test&z)

令人驚訝的是,即使沒有定義移動建構函數,此程式碼也會編譯並執行。這是因為隱式移動規則會檢查表達式 i 是否「適合移動」。在本例中,i 是局部變量,可以移動。因此,編譯器仍然可以省略複製操作。

隱式移動規則

隱式移動規則在按值返回物件時觸發,並且滿足以下條件:

  • 表示傳回值的表達式是可移動的(即,可以在不違反任何別名的情況下將其移動)
  • 沒有用戶定義的複製或移動構造函數/賦值運算符是可行的。

結論

隱式移動規則提供了一種高效、簡潔的方法按值返回物件。它有助於優化程式碼、減少不必要的複製並提高效能。然而,有必要了解它的局限性,並意識到在沒有適當考慮的情況下使用它可能會帶來的潛在問題。

以上是在 C 中按值傳回命名物件時,隱式移動規則如何運作?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

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