例外処理
プログラムを実行すると、"例外" と呼ばれる異常な条件やエラーが多数発生する可能性があります。 これには、メモリ不足、リソース割り当てエラー、およびファイルの検索エラーが含まれる場合があります。
Microsoft Foundation クラス ライブラリでは、C++ の ANSI 標準委員会によって提案されたものの後に密接にモデル化された例外処理スキームが使用されます。 異常な状況が発生する可能性のある関数を呼び出す前に、例外ハンドラーを設定する必要があります。 関数が異常な条件を検出すると、例外がスローされ、制御が例外ハンドラーに渡されます。
Microsoft Foundation クラス ライブラリに含まれるいくつかのマクロによって、例外ハンドラーが設定されます。 他の多くのグローバル関数は、特殊な例外をスローし、必要に応じてプログラムを終了するのに役立ちます。 これらのマクロとグローバル関数は、次のカテゴリに分類されます。
例外マクロ。例外ハンドラーを構成します。
例外スロー関数)。特定の型の例外を生成します。
プログラム終了の原因となる終了関数。
例と詳細については、例外に関する記事を参照してください。
例外マクロ
名前 | 説明 |
---|---|
TRY | 例外処理用のコード ブロックを指定します。 |
キャッチ | 上記の TRY ブロックから例外をキャッチするためのコード ブロックを指定します。 |
CATCH_ALL | 上記の TRY ブロックからすべての例外をキャッチするためのコード ブロックを指定します。 |
AND_CATCH | 前の TRY ブロックから追加の例外の種類をキャッチするためのコード ブロックを指定します。 |
AND_CATCH_ALL | 前の TRY ブロックでスローされた他のすべての例外の種類をキャッチするためのコード ブロックを指定します。 |
END_CATCH | 最後 の CATCH または AND_CATCHコード ブロックを 終了します。 |
END_CATCH_ALL | 最後 のCATCH_ALLコード ブロックを 終了します。 |
THROW | 指定した例外をスローします。 |
THROW_LAST | 現在処理されている例外を次の外部ハンドラーにスローします。 |
例外スロー関数
名前 | 説明 |
---|---|
AfxThrowArchiveException | アーカイブ例外をスローします。 |
AfxThrowFileException | ファイル例外をスローします。 |
AfxThrowInvalidArgException | 無効な引数例外をスローします。 |
AfxThrowMemoryException | メモリ例外をスローします。 |
AfxThrowNotSupportedException | サポートされていない例外をスローします。 |
AfxThrowResourceException | Windows リソースが見つからない例外をスローします。 |
AfxThrowUserException | ユーザーが開始したプログラム アクションで例外をスローします。 |
MFC には、OLE 例外専用の 2 つの例外スロー関数が用意されています。
OLE 例外関数
名前 | 説明 |
---|---|
AfxThrowOleDispatchException | OLE オートメーション関数内で例外をスローします。 |
AfxThrowOleException | OLE 例外をスローします。 |
データベース例外をサポートするために、データベース クラスには 2 つの例外クラスとCDaoException
、CDBException
例外の種類をサポートするグローバル関数が用意されています。
DAO 例外関数
名前 | 説明 |
---|---|
AfxThrowDAOException | 独自の コードから CDaoException をスローします。 |
AfxThrowDBException | 独自の コードから CDBException をスローします。 |
MFC には、次の終了関数が用意されています。
終了関数
名前 | 説明 |
---|---|
AfxAbort | 致命的なエラーが発生したときにアプリケーションを終了するために呼び出されます。 |
TRY
TRY ブロックを設定します。
TRY
解説
TRY ブロックは、例外をスローする可能性があるコード ブロックを識別します。 これらの例外は、次 の CATCH ブロックと AND_CATCH ブロックで処理されます。 再帰は許可されます。例外は、例外を無視するか、THROW_LAST マクロを使用して、外側 の TRY ブロックに渡すことができます。 try ブロックを END_CATCH マクロまたは END_CATCH_ALL マクロで終了します。
詳細は、例外のアーティクルを参照してください。
例
CATCH の例を参照してください。
必要条件
ヘッダー: afx.h
キャッチ
前の TRY ブロックでスローされた最初の例外の種類をキャッチするコード ブロックを定義します。
CATCH(exception_class, exception_object_pointer_name)
パラメーター
exception_class
テスト対象の例外の種類を指定します。 標準例外クラスの一覧については、CException クラスを参照してください。
exception_object_pointer_name
マクロによって作成される例外オブジェクト ポインターの名前を指定します。 ポインター名を使用して、CATCH ブロック内の例外オブジェクトにアクセスできます。 この変数は、ユーザーが宣言します。
解説
例外処理コードは、必要に応じて例外オブジェクトを問い合わせて、例外の特定の原因に関する詳細情報を取得できます。 THROW_LAST マクロを呼び出して、処理を次の外部例外フレームにシフトします。 try ブロックを END_CATCH マクロで終了します。
exception_classがクラスCException
の場合、すべての例外の種類がキャッチされます。 CObject::IsKindOf メンバー関数を使用して、スローされた特定の例外を特定できます。 複数の種類の例外をキャッチするより良い方法は、それぞれ異なる例外の種類を持つシーケンシャル AND_CATCH ステートメントを使用する方法です。
例外オブジェクト ポインターは、マクロによって作成されます。 自分で宣言する必要はありません。
Note
CATCH ブロックは、中かっこで区切られた C++ スコープとして定義されます。 このスコープで変数を宣言すると、そのスコープ内でのみアクセスできます。 これは、exception_object_pointer_nameにも適用されます。
例外と CATCH マクロの詳細については、例外に関する記事を参照してください。
例
CFile* pFile = NULL;
// Constructing a CFile object with this override may throw
// a CFile exception and won't throw any other exceptions.
// Calling CString::Format() may throw a CMemoryException,
// so we have a catch block for such exceptions, too. Any
// other exception types this function throws will be
// routed to the calling function.
TRY
{
pFile = new CFile(_T("C:\\WINDOWS\\SYSTEM.INI"),
CFile::modeRead | CFile::shareDenyNone);
ULONGLONG dwLength = pFile->GetLength();
CString str;
str.Format(_T("Your SYSTEM.INI file is %I64u bytes long.") , dwLength);
AfxMessageBox(str);
}
CATCH(CFileException, pEx)
{
// Simply show an error message to the user.
pEx->ReportError();
}
AND_CATCH(CMemoryException, pEx)
{
// We can't recover from this memory exception, so we'll
// just terminate the app without any cleanup. Normally,
// an application should do everything it possibly can to
// clean up properly and not call AfxAbort().
AfxAbort();
}
END_CATCH
// If an exception occurs in the CFile constructor,
// the language will free the memory allocated by new
// and will not complete the assignment to pFile.
// Thus, our cleanup code needs to test for NULL.
if (pFile != NULL)
{
pFile->Close();
delete pFile;
}
CATCH_ALL
前の TRY ブロックでスローされたすべての例外の種類をキャッチするコード ブロックを定義します。
CATCH_ALL(exception_object_pointer_name)
パラメーター
exception_object_pointer_name
マクロによって作成される例外オブジェクト ポインターの名前を指定します。 ポインター名を使用して、ブロック内の例外オブジェクトに CATCH_ALL
アクセスできます。 この変数は、ユーザーが宣言します。
解説
例外処理コードは、必要に応じて例外オブジェクトを問い合わせて、例外の特定の原因に関する詳細情報を取得できます。 マクロを THROW_LAST
呼び出して、処理を次の外部例外フレームにシフトします。 CATCH_ALLを使用する場合は、try ブロックを END_CATCH_ALL マクロで終了します。
Note
CATCH_ALL ブロックは、中かっこで区切られた C++ スコープとして定義されます。 このスコープで変数を宣言すると、そのスコープ内でのみアクセスできます。
例
CFile::Abort の例を参照してください。
必要条件
ヘッダー afx.h
AND_CATCH
前の TRY ブロックでスローされた追加の例外の種類をキャッチするためのコード ブロックを定義します。
AND_CATCH(exception_class, exception_object_pointer_name)
パラメーター
exception_class
テスト対象の例外の種類を指定します。 標準例外クラスの一覧については、CException クラスを参照してください。
exception_object_pointer_name
マクロによって作成される例外オブジェクト ポインターの名前。 ポインター名を使用して、AND_CATCH ブロック内の例外オブジェクトにアクセスできます。 この変数は、ユーザーが宣言します。
解説
CATCH マクロを使用して 1 つの例外の種類をキャッチし、次に後続の各型をキャッチするAND_CATCH マクロを使用します。 try ブロックを END_CATCH マクロで終了します。
例外処理コードは、必要に応じて例外オブジェクトを問い合わせて、例外の特定の原因に関する詳細情報を取得できます。 AND_CATCH ブロック内で THROW_LAST マクロを呼び出して、処理を次の外部例外フレームにシフトします。 AND_CATCHは、上記の CATCH ブロックまたは AND_CATCH ブロックの末尾をマークします。
Note
AND_CATCH ブロックは C++ スコープとして定義されます (中かっこで区切られます)。 このスコープで変数を宣言する場合は、そのスコープ内でのみアクセス可能であることに注意してください。 これは、exception_object_pointer_name変数にも適用されます。
例
CATCH の例を参照してください。
必要条件
ヘッダー afx.h
AND_CATCH_ALL
前の TRY ブロックでスローされた追加の例外の種類をキャッチするためのコード ブロックを定義します。
AND_CATCH_ALL(exception_object_pointer_name)
パラメーター
exception_object_pointer_name
マクロによって作成される例外オブジェクト ポインターの名前。 ポインター名を使用して、AND_CATCH_ALL ブロック内の例外オブジェクトにアクセスできます。 この変数は、ユーザーが宣言します。
解説
CATCH マクロを使用して 1 つの例外の種類をキャッチし、次に AND_CATCH_ALL マクロを使用して他のすべての後続の型をキャッチします。 AND_CATCH_ALLを使用する場合は、try ブロックを END_CATCH_ALL マクロで終了します。
例外処理コードは、必要に応じて例外オブジェクトを問い合わせて、例外の特定の原因に関する詳細情報を取得できます。 AND_CATCH_ALL ブロック内の THROW_LAST マクロを呼び出して、処理を次の外部例外フレームにシフトします。 AND_CATCH_ALLは、上記の CATCH ブロックまたは AND_CATCH_ALL ブロックの末尾をマークします。
Note
AND_CATCH_ALL ブロックは C++ スコープとして定義されます (中かっこで区切られます)。 このスコープで変数を宣言する場合は、そのスコープ内でのみアクセス可能であることに注意してください。
必要条件
ヘッダー afx.h
END_CATCH
最後 の CATCH ブロックまたは AND_CATCH ブロックの末尾を マークします。
END_CATCH
解説
END_CATCH マクロの詳細については、例外に関する記事を参照してください。
必要条件
ヘッダー afx.h
END_CATCH_ALL
最後のCATCH_ALL88またはAND_CATCH_ALL ブロックの末尾をマークします。
END_CATCH_ALL
必要条件
ヘッダー afx.h
THROW (MFC)
指定した例外をスローします。
THROW(exception_object_pointer)
パラメーター
exception_object_pointer
から CException
派生した例外オブジェクトをポイントします。
解説
THROW はプログラムの実行を中断し、プログラム内の関連 する CATCH ブロックに制御を渡します。 CATCH ブロックを指定していない場合は、エラー メッセージを出力して終了する Microsoft Foundation クラス ライブラリ モジュールに制御が渡されます。
詳細は、例外のアーティクルを参照してください。
必要条件
ヘッダー afx.h
THROW_LAST
例外を次の外側 の CATCH ブロックにスローします。
THROW_LAST()
解説
このマクロを使用すると、ローカルで作成された例外をスローできます。 キャッチしたばかりの例外をスローしようとすると、通常はスコープ外になり、削除されます。 THROW_LASTでは、例外は次の CATCH ハンドラーに正しく渡されます。
詳細は、例外のアーティクルを参照してください。
例
CFile::Abort の例を参照してください。
必要条件
ヘッダー afx.h
AfxThrowArchiveException
アーカイブ例外をスローします。
void AfxThrowArchiveException(int cause, LPCTSTR lpszArchiveName);
パラメーター
cause
例外の理由を示す整数を指定します。 使用可能な値の一覧については、「CArchiveException::m_cause」を参照してください。
lpszArchiveName
例外の原因となったオブジェクトの CArchive
名前を含む文字列を指します (使用可能な場合)。
必要条件
ヘッダー afx.h
AfxThrowFileException
ファイル例外をスローします。
void AfxThrowFileException(
int cause,
LONG lOsError = -1,
LPCTSTR lpszFileName = NULL);
パラメーター
cause
例外の理由を示す整数を指定します。 使用可能な値の一覧については、「CFileException::m_cause」を参照してください。
lOsError
例外の理由を示すオペレーティング システム エラー番号 (使用可能な場合) が含まれます。 エラー コードの一覧については、オペレーティング システムのマニュアルを参照してください。
lpszFileName
例外の原因となったファイルの名前を含む文字列を指します (使用可能な場合)。
解説
オペレーティング システムのエラー コードに基づいて原因を特定する必要があります。
必要条件
ヘッダー afx.h
AfxThrowInvalidArgException
無効な引数例外をスローします。
構文
void AfxThrowInvalidArgException( );
解説
この関数は、無効な引数が使用されている場合に呼び出されます。
必要条件
ヘッダー: afx.h
AfxThrowMemoryException
メモリ例外をスローします。
void AfxThrowMemoryException();
解説
基になるシステム メモリ アロケーター (malloc や GlobalAlloc Windows 関数など) の呼び出しが失敗した場合は、この関数を呼び出します。 メモリ割り当てが失敗するとメモリ例外が自動的にスローされるためnew
、呼び出すnew
必要はありません。
必要条件
ヘッダー afx.h
AfxThrowNotSupportedException
サポートされていない機能の要求の結果である例外をスローします。
void AfxThrowNotSupportedException();
必要条件
ヘッダー afx.h
AfxThrowResourceException
リソース例外をスローします。
void AfxThrowResourceException();
解説
この関数は、通常、Windows リソースを読み込むことができない場合に呼び出されます。
必要条件
ヘッダー afx.h
AfxThrowUserException
エンド ユーザー操作を停止する例外をスローします。
void AfxThrowUserException();
解説
この関数は通常、ユーザーにエラーを報告した直後 AfxMessageBox
に呼び出されます。
必要条件
ヘッダー afx.h
AfxThrowOleDispatchException
OLE オートメーション関数内で例外をスローするには、この関数を使用します。
void AFXAPI AfxThrowOleDispatchException(
WORD wCode ,
LPCSTR lpszDescription,
UINT nHelpID = 0);
void AFXAPI AfxThrowOleDispatchException(
WORD wCode,
UINT nDescriptionID,
UINT nHelpID = -1);
パラメーター
wCode
アプリケーションに固有のエラー コード。
lpszDescription
エラーの口頭での説明。
nDescriptionID
音声エラーの説明のリソース ID。
nHelpID
アプリケーションのヘルプのヘルプ コンテキスト (.HLP) ファイル。
解説
この関数に提供される情報は、運転アプリケーション (Microsoft Visual Basic または別の OLE オートメーション クライアント アプリケーション) によって表示できます。
例
// Sort is method of automation class CStrArrayDoc
long CStrArrayDoc::Sort(VARIANT* vArray)
{
USES_CONVERSION;
// Type check VARIANT parameter. It should contain a BSTR array
// passed by reference. The array must be passed by reference; it is
// an in-out-parameter.
// throwing COleDispatchException allows the EXCEPINFO structure of
// IDispatch::Invoke() to set
if (V_VT(vArray) != (VT_ARRAY | VT_BSTR))
AfxThrowOleDispatchException(1001,
_T("Type Mismatch in Parameter. Pass a string array by reference"));
// ...
// ...
return 0;
}
必要条件
ヘッダー afx.h
AfxThrowOleException
型 COleException
のオブジェクトを作成し、例外をスローします。
void AFXAPI AfxThrowOleException(SCODE sc);
void AFXAPI AfxThrowOleException(HRESULT hr);
パラメーター
Sc
例外の理由を示す OLE 状態コード。
人事
例外の理由を示す結果コードを処理します。
解説
HRESULT を引数として受け取るバージョンは、その結果コードを対応する SCODE に変換します。 HRESULT と SCODE の詳細については、「Windows SDK での COM エラー コードの構造」を参照してください。
必要条件
ヘッダー afxdao.h
AfxThrowDaoException
独自のコードから CDaoException 型の例外をスローするには、この関数を呼び出します。
void AFXAPI AfxThrowDaoException(
int nAfxDaoError = NO_AFX_DAO_ERROR,
SCODE scode = S_OK);
パラメーター
nAfxDaoError
DAO 拡張エラー コードを表す整数値。これは、CDaoException::m_nAfxDaoError に記載されている値のいずれかになります。
Scode
SCODE 型の DAO の OLE エラー コード。 詳細については、「CDaoException::m_scode」を参照 してください。
解説
フレームワークも呼び出します AfxThrowDaoException
。 呼び出しでは、いずれかのパラメーターまたは両方を渡すことができます。 たとえば、CDaoException::nAfxDaoError で定義されているエラーの 1 つを発生させるが、scode パラメーターを気にしない場合は、nAfxDaoError パラメーターに有効なコードを渡し、scode の既定値を受け入れます。
MFC DAO クラスに関連する例外の詳細については、本書のクラスCDaoException
と、例外: データベース例外に関する記事を参照してください。
必要条件
ヘッダー afxdb.h
AfxThrowDBException
この関数を呼び出して、独自のコードから型 CDBException
の例外をスローします。
void AfxThrowDBException(
RETCODE nRetCode,
CDatabase* pdb,
HSTMT hstmt);
パラメーター
nRetCode
例外がスローされる原因となったエラーの種類を定義する RETCODE 型の値。
Pdb
例外が CDatabase
関連付けられているデータ ソース接続を表すオブジェクトへのポインター。
Hstmt
例外が関連付けられているステートメント ハンドルを指定する ODBC HSTMT ハンドル。
解説
フレームワークは、ODBC API 関数の呼び出しから ODBC RETCODE を受け取ると呼び出 AfxThrowDBException
し、RETCODE を予期されるエラーではなく例外的な条件として解釈します。 たとえば、ディスク読み取りエラーが原因でデータ アクセス操作が失敗する場合があります。
ODBC で定義された RETCODE 値の詳細については、Windows SDK の第 8 章「状態とエラー情報の取得」を参照してください。 これらのコードに対する MFC 拡張機能の詳細については、CDBException クラスを参照してください。
必要条件
ヘッダー afx.h
AfxAbort
MFC によって提供される既定の終了関数。
void AfxAbort();
解説
AfxAbort
は、処理できないキャッチされない例外などの致命的なエラーがある場合に、MFC メンバー関数によって内部的に呼び出されます。 回復できない致命的なエラーが発生した場合は、まれなケースで呼び出 AfxAbort
すことができます。
例
CATCH の例を参照してください。
必要条件
ヘッダー afx.h