C++/CLIをつつく24-例外処理。緊急事態発生!隊長報告します!
ピキュピキュピキュピキュピキュピキュピキュピキュピキュピキュピキュピキュピキュピーン♪
閃いたぞ。例外をつつこう。例外とは何かというと、ひとまずエラーの通知処理だと思って。それじゃあ、いつものように、行くぞー。とぉー。
#include "stdafx.h"
using namespace System;
ref class ExceptionTest {
public :
static void ArgumentException( ) {
ArgumentException2( );
}
static void ArgumentException2( ) {
throw gcnew System::ArgumentException( L"例外を強制発生させたピヨ。");
}
};
int main(array< System::String ^> ^args)
{
try {
ExceptionTest::ArgumentException( );
Console::WriteLine("ここは絶対実行されません。");
}
catch ( ArgumentException^ e ) {
Console::WriteLine( "例外がスローされました。詳細は次の通りピヨ。\n");
Console::WriteLine( "例外のメッセージ{0}\n", e->Message );
Console::WriteLine( "スタックトレース{0}\n", e->StackTrace);
Console::WriteLine( "例外の発生源となったオブジェクト{0}\n", e->Source );
}
finally {
Console::WriteLine( "ここは絶対実行されるピヨッ。\n" );
}
return 0;
}
まずはこのコードをステップ実行してみて。そうすれば、例外の大まかな動きはわかると思う。
やってみた?じゃあ解説するピヨ。
.NETの例外処理で重要な要素は4個あるピヨ。まず1つ目は、tryブロックピヨ。tryブロック内には処理が失敗することが予想される処理を記述するピヨ。今回のサンプルプログラムの場合、絶対例外が発生するのがわかっているから簡単だけど、実務ではこれは案外難しいことなんだ。その理由は後で話すよ。
2つ目の要素はcatchブロックピヨ。 このブロックは予想される例外オブジェクトを指定して、 その例外に対してするべき処理を書くんだ。でも出来る事といっても大概はエラーだから、 このサンプルプログラムのようにプログラマに報告することぐらいしか出来ない場合が多いピヨ。
3つ目の要素はfinallyブロックピヨ。このブロックは必ず実行したい処理がある場合に用意するピヨ。例えば、データベースへのConnectionを開放するとか、ファイルオブジェクトを開放するとか、そんな事に使用するんだ。
最後の要素はthrowメソッドピヨ。例外を受け取る機構があるということは、例外を発生させる文法が必要になるよね。それがC#ではthrowメソッドなんだ。 このメソッドを使うとtryブロックが無いとプログラムが異常終了するから多用は駄目ピヨ。 実際にどうなるか試してみよう。
#include "stdafx.h"
using namespace System;
ref class ExceptionTest {
public :
static void ArgumentException( ) {
ArgumentException2( );
}
static void ArgumentException2( ) {
throw gcnew System::ArgumentException( L"例外を強制発生させたピヨ。");
}
};
int main(array< System::String ^> ^args)
{
ExceptionTest::ArgumentException( );
try {
Console::WriteLine("ここは絶対実行されません。");
}
catch ( ArgumentException^ e ) {
Console::WriteLine( "例外がスローされました。詳細は次の通りピヨ。\n");
Console::WriteLine( "例外のメッセージ{0}\n", e->Message );
Console::WriteLine( "スタックトレース{0}\n", e->StackTrace);
Console::WriteLine( "例外の発生源となったオブジェクト{0}\n", e->Source );
}
finally {
Console::WriteLine( "ここは絶対実行されるピヨッ。\n" );
}
return 0;
}
実行してごらん。変なメッセージが出るよ。
System.ArgumentException はハンドルされませんでした。
これは、対応するcatchブロックが無いことを示しているんだ。つまり、解決できない状況になっているという深刻な状態なんだ。だからといって、これは駄目だよ。
catch (Exception^ e) {
//全部隠しちゃえ!
}
こんな事をしてしまったら発生した問題が誰にもわからないまま放置されてしまう。これは問題解決になっておらず、事件を隠蔽しているだけだから絶対しちゃ駄目だよ。次回へ続く・・・