この記事では、 try-catch-finally
ブロックを使用して例外をキャッチする方法について説明します。
元の製品バージョン: Visual C++
元の KB 番号: 815662
まとめ
try-catch-finally
ブロックは、例外が発生する可能性があるコードを囲むラッパーです。 例外のキャッチと処理は、標準的なプログラミング タスクです。
try-catch-finally
ブロックは、次のセクションで構成されています。
- 例外をスローする可能性のあるコードは、try ブロック内に配置されます。
- 例外がスローされた場合、
catch
ブロックが入力され、プログラムは適切な操作を実行して回復またはユーザーに警告することができます。 finally
ブロック内のコードは常に実行され、例外が発生した後にクリーンアップできます。finally
ブロックは省略可能です。
この記事では、Microsoft .NET Framework クラス ライブラリの名前空間 ( System.IO
と System.Security
) について説明します。
Visual C++ .NET で例外をキャッチする
Visual Studio .NET を起動します。
[ファイル] メニューの [新規作成] をポイントし、 [プロジェクト] をクリックします。
Visual C++ で、Project 型の下の Visual C++ をクリックし、Templates の下にある CLR コンソール アプリケーションをクリックします。
[ 名 ボックスに「 Q815662」と入力し、[ OK] をクリック。
Q815662.cpp コード ウィンドウ内のすべてのコードを次のコードに置き換えます。 このコードでは、3 つの変数を宣言して初期化します。 kの初期化によってエラーが発生します。
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; void _tmain(void) { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. }
F5キーを押します。
System.DivideByZeroException
例外が発生します。try-catch
ステートメントをコードの周囲にラップして、エラーをキャプチャします。 次のコードは、コードでスローされたすべてのエラーをキャッチし、一般的なエラー メッセージを表示します。 Q815662.cpp コード ウィンドウのコードを次のコードに置き換えます。#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; void _tmain(void) { try { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. } catch(...) { Console::WriteLine("An error occurred."); } }
Ctrl キーを押しながら F5 キーを押してアプリケーションを実行します。
Note
システム例外エラー メッセージの代わりに、
catch
ブロックからのエラー メッセージが表示されます。エラーに関係なくクリーンアップまたは後処理を行う必要がある場合は、
try-catch-finally
ステートメントの__finally
部分を使用します。 ステートメントの最後の部分のコードは、例外に関係なく常に実行されます。 次のコードは、エラーが発生していなくても、コンソールに次のメッセージを表示します。This statement is always printed.
Q815662.cpp コード ウィンドウのコードを次のコードに置き換えます。
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; void _tmain(void) { try { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. } catch(...) { Console::WriteLine("An error occurred."); } __finally //This section is performed regardless of the above processing. { Console::WriteLine(); Console::WriteLine("This statement is always printed"); } }
Ctrl キーを押しながら F5 キーを押してプロジェクトを実行します。
例外オブジェクトを catch ステートメントと共に使用して、例外に関する詳細を取得できます。 例外オブジェクトには、ソースを識別するのに役立つさまざまなプロパティがあり、例外に関するスタック情報があります。 この情報は、例外の元の原因を追跡するのに役立つ場合や、そのソースのより適切な説明を提供するのに役立ちます。 次の例では、例外をキャッチし、特定のエラー メッセージを表示します。 Q815662.cpp コード ウィンドウのコードを次のコードに置き換えます。
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; using namespace System::Reflection; void _tmain(void) { try { Console::WriteLine("We're going to divide 10 by 0 and see what happens..."); Console::WriteLine(); int i = 10; int j = 0; int k = i/j; //Error on this line. } catch(Exception *e) { Console::WriteLine("An error occurred."); Console::WriteLine(e->Message); // Print the error message. Console::WriteLine(e->StackTrace); //String that contains the stack trace for this exception. } __finally //This section is performed regardless of the above processing. { Console::WriteLine(); Console::WriteLine("This statement is always printed"); } Console::ReadLine(); }
この時点まで、特定以外の例外を処理しました。 ただし、発生する例外の種類が事前にわかっている場合は、予期される例外をキャッチし、それに応じて処理できます。 次のコードで説明されている複数の catch ブロックを使用して、他のすべての例外をキャッチして処理します。
#include "stdafx.h" #using <mscorlib.dll> #include <tchar.h> using namespace System; using namespace System::IO; using namespace System::Security; void _tmain(void) { try { File::Create("c:\\temp\\testapp.txt"); //Can fail for a number of resons } // This error may occur if the temp folder does not exist. catch(IOException *ioe) { Console::WriteLine("An IOException exception occurred!"); Console::WriteLine(ioe->ToString()); } // You do not have the appropriate permission to take this action. catch(SecurityException *se) { Console::WriteLine("An SecurityException exception occur") } // Catch all exceptions catch(Exception *e) { Console::WriteLine(e->ToString()); } }
コンピューターの構成が異なる場合があるため、この手順のサンプルでは例外がスローされる場合とスローされない場合があります。 入力/出力 (IO) 例外を強制する場合は、コンピューターに存在しないフォルダーにファイル パスを変更します。