2

「スマート ポインター」として機能し、破棄されたときにある種のシステム リソースを解放するクラスがあるとします。

class Resource{
protected:
     ResourceHandle h;
public:
     Resource(ResourceHandle handle)
     :h(handle){
     }

     ~Resource(){
         if (h)
             releaseResourceHandle(h);//external function, probably from OS
     }
};

そして、「リソース」の初期化に使用される値を返す関数がいくつかあります。

ResourceHandle allocateHandle();

今、私のコードでこれを行うと:

Resource resource(allocateHandle());

AND allocateHandle()が例外をスローすると、正確にはどうなりますか? クラッシュは Resource() の構築中または構築前に発生しますか?

常識的に言えば、allocateHandle が戻る前に例外がスローされるため、実行は Resource() コンストラクターに入るまでもありませんが、正確にはわかりません。これは正しい仮定ですか?

4

5 に答える 5

4

引数は、関数呼び出し (この場合はコンストラクター) の前に評価されます。したがって、例外はコンストラクター呼び出しの前にスローされます

于 2010-07-25T14:56:41.890 に答える
3

はい、あなたは正しいです(他のみんなが言ったように)。

しかし、あなたがほのめかしていること(私は思う)。
コンストラクターに入って例外がスローされた場合、オブジェクトはどうなりますか。

デストラクタはまだ実行されますか?

デストラクタは、コンストラクタが実際に終了した場合にのみ起動されます (コンストラクタをエスケープする例外がスローされた場合、コンストラクタは終了していません)。この場合、コンストラクターが入力されていないため、オブジェクトが存在しないため、デストラクタは実行されません。

コンストラクターの実行中に例外がスローされるとどうなりますか。
この場合、コンストラクタが完了していないため、デストラクタも実行されませんが、すべてのメンバー フィールドはどうでしょうか。コンストラクターが例外によって残された場合、完全に形成されたすべてのメンバーのデストラクタが呼び出されます (完全に形成されたメンバーとは、コンストラクターが呼び出されて正常に完了したメンバーです)。

于 2010-07-25T17:01:35.740 に答える
1

これは正しい仮定です。

于 2010-07-25T14:55:56.010 に答える
1

コンパイラがコンストラクタに入った場合、返されなかった関数からどのような値を渡すことができますか?

于 2010-07-25T14:59:25.287 に答える
0

はい、あなたの仮定は正しいです。

この時点では、パラメータを作成してスタックにプッシュするだけです。「リソース」のオブジェクトも形成されていません!

したがって、スタックの巻き戻し中に例外がデストラクタを呼び出すことはありません。

于 2010-07-25T14:59:11.080 に答える