質問
次のコードを考えてみます:
#include <iostream>
#include <stdexcept>
void foo()
{
throw std::runtime_error("How long do I live?");
}
int main()
{
try
{
foo();
}
catch (std::runtime_error& e)
{
std::cout << e.what() << std::endl;
}
}
なぜ私は参照することにより、例外をキャッチすることができ、右辺値をstd::runtime_error("How long do I live?")
されていない?
どのように来る例外オブジェクトがcatchブロックでまだ生きているのですか?
どこに正確にスローされた例外オブジェクトが格納されていますか?彼らの寿命は何ですか?
正しい解決策はありません
他のヒント
C ++標準では、段落15.1.4ます:
標準話、ハンドラが正しい引数の型との一時コピー用のメモリ スローされる例外はあります 未指定の方法で割り当てられ、 3.7.3.1に記載されている場合を除き。 <強いです> 一時的には限りがある限り持続します そのために実行されるハンドラ 例外の。具体的には、もし ハンドラはスローを実行することで終了します。 文に制御を渡します。 同じのための別のハンドラ 例外なので、一時的な遺跡。 最後のハンドラが実行された場合 任意の手段によって例外終了のため ;投げる以外の一時オブジェクト 破壊され、実装されます 以下のためにメモリを解放します 一時的なオブジェクト。そのような 解除は不定で行われます 仕方。破壊が起こります すぐに破壊した後 で宣言されたオブジェクト ハンドラで例外宣言ます。
catch
ブロックを示す - C ++で、あることに注意してください。
スローされた例外は、一時的ではありません - コンパイラが生成した例外コードは、それの永続的なコピーを保持します。だから、非const参照にバインドすることができます。
[編集] 私は、標準をチェックし、それが実際に一時的なコピーを指します。しかし、一時的の寿命は、例外ハンドラのそれと少なくとも同じ長であることが保証されます。
、起こって内部コンパイラの魔法があります。また、コンパイラは、をいくつでも作成することが許可されていることに注意してください例外オブジェクトのコピーでます。
言語の詳細を理解しようとするために拍手を送りたいです。同時に、私見、それはあなたがの理由を理解することがはるかに重要であるは参照することにより、例外をキャッチ(および値によって、それを投げる)する必要があり、あなたはをなぜよりのことができます。
人々は通常、例外クラスの階層を使用して、参照することによって引くことはあなたがポリモーフィズムを活用し、個別に個々の例外タイプを処理する必要がない場合には、基底クラスの例外をキャッチすることができます。あなたが参照して捕まえることができなかった場合は、catch
句にスローされる可能性が例外の可能なすべての種類のためのtry
句を書かなければならなかったでしょう。