ホームに戻る
関連 :
例外クラス RAIIと地蔵インスタンス [C#]例外処理(try - catch - finally)
目次 :

例外処理(exception handling)とは

実行時エラーを管理し、処理する機構。
エラー(例外)発生時の処理を体系的に、また集約して実装することができる。
C++に限らず、オブジェクト指向言語においては一般的な概念。
尚、例外を発行することを慣例的に「例外を投げる(throw exception)」という。

例外処理の原則

C++における例外処理の原則は以下の通りである。

基本的な例

画像
上記の例では、関数 func() 中の try 節に含まれる func2() 、DoSomething() が例外監視対象となる。
func2() では内部で int 型例外を投げ( throw )ており、try 節に続く catch (int ex) 節で例外が捕捉される。
(int 型と異なる型の例外が投げられた場合は、後続の catch (string ex) 節、または catch (...) 節で捕捉される。)

例外の投げなおし

try ブロックで発生した例外を処理した後、さらに外側に例外を投げることができる。
当然、try ブロックは(コールスタック全体で)ネストしている必要がある。

捕捉した例外と異なる例外を投げる

画像
catch 節内に throw 句を記述することで、さらに外側に例外を投げる。
このとき、捕捉した例外と型や値が一致している必要はない。

捕捉した例外をそのまま投げなおす

捕捉した例外をそのまま投げなおす場合は、throw のみを記述する。
void func1() { try { // ここで例外発生 func2(); } catch (exception ex) { // 例外を投げなおす throw; // これは誤り // throw ex; } }
上記のコードでは例外 ex を捕捉し、外側に投げなおしている。
このときthrow ex;とすると、ex が投げられた時点でのコールスタック情報( func2() )しか記録されないため、
func1() が例外を投げ(なおし)たことがわからなくなる。
単にthrow;とすることで、投げなおした func1() の情報も追加される。
投げなおされる例外の型は ex と共通である。

例外送出有無の表明 ( noexcept )

noexcept 句を使用することで、関数が例外を送出しない(または逆に、する可能性がある)ことを明確化することができる。
例外を送出しないことを明示すると巻き戻すためのスタックが確保されなくなるため、スタック使用量を削減することができる。
// 例外を送出しない void f() noexcept; void f() noexcept(true); // 例外を送出する(可能性がある) void f() noexcept(false); void f();
過去には、throw 句を用いて送出例外の型を制限する記法も存在したが、これはあまり有用ではないことから
C++11で非推奨となり、C++17で削除された。

C++標準の例外クラス

C++の標準ライブラリには、例外として送出するためのクラス(例外オブジェクト)が定義されている。詳細はここを参照。