1

次の状況を考慮してください。

struct X { ... };

struct Y
{
     Y(...);

     ...

     X x;

     ...
}

X f()
{
    ...

    if (...)
        throw E;

    ...
}

Y::Y(...) :
    ... ,
    x(f()) ,
    ...
{
    ...
}

ここに未定義の動作はありますか?Eが投げられたとき、そのようなデザインに落とし穴や潜在的な問題はありますか?

アップデート:

Y::xの唯一のメンバー変数ではない可能性があり、クラスの最初のメンバー変数ではない可能性があり、 initリストYの途中で初期化される可能性があります。Y::Y

4

2 に答える 2

5

ここに未定義の動作はありますか?

いいえ。 の建設Yは中止されました。

E がスローされたときに、そのような設計に落とし穴や潜在的な問題はありますか?

NoYが作成されることはないため、呼び出すデストラクタはありません。クラス本体で以前に宣言された、完全に構築された要素のデストラクタは、x自動的に呼び出されます (そうでなければ、初期化リストがスローされたときにどのくらい離れていたかがわかります)。何かを破棄する必要がある場合は、例外をキャッチして自分で破棄する必要があります。例外を吸収することはできません。例外を再スローするか、新しい例外をスローするか、例外が再スローされることになる何もしないでください。特定のユースケースでは、コンストラクター本体がまったく呼び出されないため、破棄するものは何もないはずです。

于 2013-01-06T22:03:05.873 に答える
2

オブジェクトの構築中に例外がスローされると、完全に構築されたすべてのサブオブジェクトのデストラクタが呼び出されます。つまりX、例外をスローする型が、例外がスローされる前に割り当てられた可能性のあるリソースを正しくクリーンアップすると仮定すると、問題はありません。

于 2013-01-06T22:16:04.127 に答える