2009-10-31 10 views
32

C++の例外オブジェクトの有効範囲はどのくらいですか? catchハンドラが実行されるとすぐにスコープを外れますか?また、名前のない例外オブジェクトを作成してそれをスローすると、その例外をキャッチしている間に、const参照または非const参照によってそれをキャッチするかどうかが重要になります。C++の例外オブジェクトの範囲

+3

*生涯*についてお尋ねしますか? – Joren

+0

はい。それが破壊されるのはいつですか? – Naveen

+8

Jorenの質問を明確にするために、_scope_という用語は通常、変数が名前を持つ領域(コード行)を参照します。_scope_という単語は、_lifetime_を意味するためによく誤用されます。これは、あなたが理解したように、変数が実際にメモリに常駐する期間です。 – Thomas

答えて

32

throw式が評価されると、例外オブジェクトは式の値から初期化されます。 throwされる例外オブジェクトは、constvolatileの修飾子を無視して、その型をスロー式の静的型から取得します。クラスタイプの場合、これはコピー初期化が実行されることを意味します。

例外オブジェクトのスコープは、スローが発生するブロックの範囲外です。ローカルオブジェクトが存在する通常のコールスタックの片側にある特別な例外領域に住んでいると考えてください。

catchブロックの中で、キャッチされた例外オブジェクトで初期化された名前は、この例外オブジェクトで初期化され、throwの引数ではなく、lvalueであっても初期化されます。

const以外の参照でcatchを使用している場合は、例外オブジェクトを変更できますが、初期化されたものは変更できません。値またはconst参照(const_castを脇に)でキャッチした場合に例外を再スローすることができない場合は、プログラムの動作を変更できます。

例外オブジェクトは、再スロー(つまり、パラメータなしのスロー式評価)によって終了しない最後のキャッチブロックが完了すると破棄されます。

4

まず、投げたオブジェクトは、ほぼすぐに範囲外になります。例外ハンドラが捕まえることになるのは、元のオブジェクトのコピーです。キャッチハンドラが実行された後、(参照ではなく)値でキャッチしない限り、そのコピーは削除されます。この場合、別のコピーが作成されます。しかし、とにかくそれを参照(できればconst one)する必要があります。

+0

MFCごとに何かにポインタを投げるのはどうですか?あなたは、質問とあなたの答えに暗示されているクラス型のオブジェクト以外のオブジェクトを考慮する必要があります。 – Sam

+0

ポインタもコピーされますが、誰も気にしません:) – vava

8

例外オブジェクトはcatchブロックでのみ使用可能です。 catchブロックの外に例外オブジェクトを使用することはできません。

try 
{ 
MyException anObject; 
throw anObject; //1 

} 
catch(MyException exObject) 
{ 
} 
  • throw句(// 1)ローカルオブジェクトanObjectを受け取り、値の引数として扱われます:あなたは例外とキャッチを投げるとき、次の手順に起こり、それがanObjectのコピーを作成します。
  • catchハンドラは、値パラメータであるMyExceptionオブジェクトをキャッチします。この時点で別のコピーが作成されます。
  • ハンドラがオブジェクト(catch (MyException &o))への参照を受け取るように実装された場合、2番目のコピーは回避されます。
  • ハンドラが例外オブジェクトをconst&で受け取った場合は、constメソッドのみを呼び出すことができます。
関連する問題