ホームページ  >  記事  >  バックエンド開発  >  この場合、C 11 Move コンストラクターが呼び出されないのはなぜですか?

この場合、C 11 Move コンストラクターが呼び出されないのはなぜですか?

Susan Sarandon
Susan Sarandonオリジナル
2024-11-05 01:49:02448ブラウズ

Why Doesn't My C  11 Move Constructor Get Called in This Case?

C 11 Move コンストラクターは呼び出されません、デフォルト コンストラクターが優先されます

問題

次のクラスを考えてみましょう:

<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">X x("test");
cout << x.c() << endl;
X y(x);
cout << y.c() << endl;
X z( X("test") );
cout << z.c() << endl;</code>

出力は次のとおりです:

ctor
test
copy
test
ctor   <-- why not move?
test

VS2010 では、デフォルト設定を使用すると、最後のオブジェクト (z) がデフォルトで構築されるのではなく移動で構築されることが期待されます。 。 X z( move(X("test")) ) を使用すると、予想される出力 ctor move test が得られます。これは NRVO のケースでしょうか?

質問

C 11 標準に従って移動コンストラクターを呼び出す必要がありますか?もしそうなら、なぜそれが呼び出されないのでしょうか?

回答

観察された動作はコピー省略によるものです。コンパイラーは、一時オブジェクトをコピー/移動先のターゲットに直接構築できるため、コピー/移動コンストラクターとデストラクターの呼び出しを省略できます。

コピー省略が適用できる状況については、§12.8 で概説されています。 C 11 標準の 32:

  • クラス戻り型を持つ関数内で、戻り式が戻り値の型と同じ型を持つ不揮発性自動オブジェクト。
  • throw 式内で、オペランドが外側の try-block を超えないスコープを持つ不揮発性自動オブジェクトである場合。
  • 参照にバインドされていないクラス オブジェクトが同じ型のクラス オブジェクトにコピーまたは移動される場合。
  • 例外ハンドラーが実行される場合例外宣言をエイリアスとして扱うことにより、例外オブジェクトと同じ型のオブジェクトを宣言します。

この場合、コンパイラは一時 X( "test") とターゲット z を組み合わせて、観察された動作をもたらします。

以上がこの場合、C 11 Move コンストラクターが呼び出されないのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。