當從函數以值傳回類別的物件時,隱式移動規則來自進入遊戲。此規則控制編譯器在建構臨時物件來保存傳回值時的行為。
考慮以下程式碼片段:
<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)。
現在,讓我們修改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中文網其他相關文章!