」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 按值返回物件何時觸發移動建構函數?

按值返回物件何時觸發移動建構函數?

發佈於2024-11-16
瀏覽:828

When Does Returning an Object by Value Trigger a Move Constructor?

以值從函數傳回類別的物件

考慮從函數傳回類別的物件的情況價值。在這種情況下,傳回的物件通常被視為左值,這意味著它在記憶體中具有名稱和位址。然而,某些情況下可能會導致傳回的物件被視為右值,即沒有名稱或位址的臨時物件。

隱式移動規則

C 定義了按值傳回物件時可能會應用的隱式移動規則。該規則規定,如果滿足以下條件:

  • 傳回的表達式是xvalue(表示不是左值的臨時物件的表達式)。
  • 傳回的物件具有移動建構函式。
  • 移動建構子是可存取的。

在這種情況下,將呼叫移動建構函式而不是複製建構函式。此行為旨在透過避免不必要的複製來優化效能。

範例1

在此範例中,傳回的物件i 是左值,因此複製建構函式test( const test& z) 被呼叫:

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 Some_thing() {
    test i;
    return i;
}

輸出:

test()
test(const test&z)

範例2

但是,在下面的範例中,傳回的物件i 被視為xvalue,移動建構函式test( test&& s)被調用,因為該物件是臨時的並且移動構造函數是可行的:

class test {
public:
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(test&& s) { printf("test(test&& s)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

輸出:

test()
test(test&& s)

範例3

如果未提供或明確刪除移動建構函數,則無法應用隱式移動規則,且程式將無法編譯:

class test {
public:
    test(test&& z) = delete;
    test(int y) { printf("test(int y)\n"); }
    test() { printf("test()\n"); }
    test(const test& z) { printf("test(const test&z)\n"); }
};
test Some_thing() {
    test i;
    return i;
}

結論

當按值傳回物件時,在特定條件下可能會套用隱式移動規則,導致呼叫移動建構函式。了解這種行為對於優化程式碼和防止編譯錯誤至關重要。

最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3