C オブジェクトを独自のコンストラクターに渡すのは合法ですか?
次のようなコードが機能するように見えるのは当惑しています:
#include <iostream> struct Foo { Foo(Foo& bar) { std::cout << &bar << std::endl; } }; int main(int argc, char** argv) { Foo foo(foo); // I can't believe this works... std::cout << &foo << std::endl; // but it does... return 0; }
初期化されていないオブジェクトのアドレスを独自のコンストラクターに渡すことにより、循環定義を確立しているように見えます。疑問が生じます。標準では、オブジェクトを構築する前に関数にオブジェクトを渡すことが許可されていますか?それとも、これは未定義の動作に該当しますか?
合法ではありますが、珍しいことではありません
初期化されていないオブジェクトのアドレスを独自のコンストラクターに渡すことは、未定義の動作ではありません。 foo は初期化されていませんが、標準で承認された方法で使用します。
完全な初期化の前にオブジェクト メモリの割り当てが行われます。したがって、この間隔では、このような変数への参照のバインドとそのアドレスの取得が許可されます。
この動作は、そのような状況で作成された参照が有効であるとみなされることを明確にする欠陥レポート 363 に準拠しています。 C 14 標準のセクション 3.8 [basic.life] では、割り当てられたが初期化されていないオブジェクトを参照する glvalue の使用が制限内で許容されるとさらに指定しています。
つまり、左辺値から右辺値への変換を適用したり、非静的アクセスにアクセスしたりすることはできません。データ メンバーや非静的メンバー関数の呼び出し、仮想基本クラス参照へのバインド、dynamic_cast や typeid の使用などを行います。
この例では、これらの禁止されたアクションを回避し、参照をバインドしてアドレスを取得します。
コンパイラの警告
動作の正当性にも関わらず、Clang は次の警告を発行します。
warning: variable 'foo' is uninitialized when used within its own initialization [-Wuninitialized]
初期化されていないオブジェクトから不定の値が生成されるため、この警告は正当化されます。自動変数は未定義の動作を構成します。それにもかかわらず、私たちの使用は不定の値を生成しないため、合法です。
さらなる考慮事項
一方、オブジェクトを独自のコンストラクターに渡すことによる自己初期化は、本質的にはそうではありません。有益または推奨される、クラスの動作を調査するための興味深い方法となる可能性があります。ただし、int x = x; のような代入による自己初期化は、未定義の動作となります。
以上がC オブジェクトを独自のコンストラクターに渡すことは合法ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。