例外の巻き戻し(C++)

提供: RAD Studio
移動先: 案内検索

C++ における標準的な例外処理 への移動


例外が送出されると、ランタイム ライブラリ(RTL)は送出されたオブジェクトを受け取り、そのオブジェクトの型を取得し、その型に一致する型を持つハンドラをコール スタック内で探します。ハンドラが見つかったら、RTL はそのハンドラの位置までスタックを巻き戻し、そのハンドラを実行します。

巻き戻しの過程で、RTL は、例外の送出位置から捕捉位置までのスタック フレームに存在するすべてのローカル オブジェクトのデストラクタを呼び出します。デストラクタが原因でスタックの巻き戻し中に例外が発生し、そのデストラクタで処理されない場合は、terminate が呼び出されます。デストラクタはデフォルトで呼び出されますが、-xd コンパイラ オプションを使用すれば、デフォルトで呼び出されないようにすることができます。

メモ: 巻き戻しの過程で、スタックではなくヒープに割り当てられたオブジェクトのデストラクタを RTL が呼び出すことはありません。そのため、たとえば VCL アプリケーションでは、finally ブロックを使用することで、常にヒープ上に割り当てられる VCL オブジェクトが適切に解放されるよう保証します。このルールには 1 つだけ例外があります。安全なポインタの使用です。

RAII ラッパーを使用したポインタの自動破棄

ローカル変数があり、それらがオブジェクトへのポインタで、例外が送出された場合、これらのポインタは自動的には削除されません。その理由は、その関数にのみ割り当てられたデータを指すポインタとそれ以外のあらゆるポインタをコンパイラが区別するための良い方法がないからです。ローカルに使用するために割り当てられたオブジェクトが例外発生時に必ず破棄されるようにするためのクラスが unique_ptr です。以下のように、関数内で割り当てられたポインタのメモリが解放される特別な場合があります。

 std::unique_ptr<TMyObject> obj(new TMyObject());

この例では、TMyObject のコンストラクタが例外を送出した場合、割り当てられた obj オブジェクトを指すポインタは、RTL により例外が巻き戻されるときに削除されます。コンパイラがポインタ値を自動的に削除するのは、この場合だけです。

メモ:unique_ptr は、auto_ptr と似たクラス テンプレートですが、より優れた方法です(auto_ptr は推奨されていません)。

関連項目