「労働者が自分の仕事をうまくやりたいなら、まず自分の道具を研ぎ澄まさなければなりません。」 - 孔子、「論語。陸霊公」
表紙 > プログラミング > オブジェクトを値で返すと移動コンストラクターがトリガーされるのはどのような場合ですか?

オブジェクトを値で返すと移動コンストラクターがトリガーされるのはどのような場合ですか?

2024 年 11 月 16 日に公開
ブラウズ:249

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

値によって関数からクラスのオブジェクトを返す

関数からクラスのオブジェクトを値によって返す場合を考えてみましょう。価値。このシナリオでは、返されるオブジェクトは通常、左辺値とみなされます。これは、オブジェクトがメモリ内に名前とアドレスを持っていることを意味します。ただし、特定の状況では、返されたオブジェクトが右辺値、つまり名前やアドレスのない一時オブジェクトとして扱われる可能性があります。

暗黙的な移動ルール

C では、オブジェクトを値で返すときに適用される暗黙的な移動ルール。このルールは、次の条件が満たされる場合に指定します。

  • 返される式は xvalue (lvalue ではない一時オブジェクトを示す式) です。
  • The class of the返されたオブジェクトには移動コンストラクターがあります。
  • 移動コンストラクターはアクセス可能です。

このような場合、コピー コンストラクターの代わりに移動コンストラクターが呼び出されます。この動作は、不必要なコピーを回避してパフォーマンスを最適化することを目的としています。

例 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