例外処理
プログラムを実行すると、"例外" と呼ばれる異常な条件やエラーが多数発生する可能性があります。 これには、メモリ不足、リソース割り当てエラー、およびファイルの検索エラーが含まれる場合があります。
Microsoft Foundation クラス ライブラリでは、C++ の ANSI 標準委員会によって提案されたものの後に密接にモデル化された例外処理スキームが使用されます。 異常な状況が発生する可能性のある関数を呼び出す前に、例外ハンドラーを設定する必要があります。 関数が異常な条件を検出すると、例外がスローされ、制御が例外ハンドラーに渡されます。
Microsoft Foundation クラス ライブラリに含まれるいくつかのマクロによって、例外ハンドラーが設定されます。 他の多くのグローバル関数は、特殊な例外をスローし、必要に応じてプログラムを終了するのに役立ちます。 これらのマクロとグローバル関数は、次のカテゴリに分類されます。
例外マクロ。例外ハンドラーを構成します。
例外スロー関数)。特定の型の例外を生成します。
プログラム終了の原因となる終了関数。
例と詳細については、 Exceptionsに関する記事を参照してください。
例外マクロ
名前 | 説明 |
---|---|
試みる | 例外処理用のコード ブロックを指定します。 |
捕まえる | 前の 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 例外をスローします。 |
データベース例外をサポートするために、データベース クラスには、 CDBException
と CDaoException
の 2 つの例外クラスと、例外の種類をサポートするグローバル関数が用意されています。
DAO 例外関数
名前 | 説明 |
---|---|
AfxThrowDAOException | 独自のコードから CDaoException をスローします。 |
AfxThrowDBException | 独自のコードから CDBException をスローします。 |
MFC には、次の終了関数が用意されています。
終了関数
名前 | 説明 |
---|---|
AfxAbort | 致命的なエラーが発生したときにアプリケーションを終了するために呼び出されます。 |
TRY
TRY ブロックを設定します。
TRY
解説
TRY ブロックは、例外をスローする可能性があるコード ブロックを識別します。 これらの例外は、次の CATCH および AND_CATCH ブロックで処理されます。 再帰は許可されます。例外は、外側の TRY ブロックに渡すことができます。例外は無視するか、THROW_LAST マクロを使用して渡すことができます。 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 マクロの詳細については、 Exceptionsに関する記事を参照してください。
例
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を使用する場合は、END_CATCH_ALL マクロで TRY ブロックを終了します。
Note
CATCH_ALL ブロックは、中かっこで区切られた C++ スコープとして定義されます。 このスコープで変数を宣言すると、そのスコープ内でのみアクセスできます。
例外の詳細については、exceptions記事を参照してください。
例
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 マクロの詳細については、 Exceptionsに関する記事を参照してください。
要件
ヘッダー 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 エラー コードの構造 」を参照してください。
要件
Header 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
および「Exceptions: データベース例外」 の記事を参照してください。
要件
Header afxdb.h
AfxThrowDBException
この関数を呼び出して、独自のコードから CDBException
型の例外をスローします。
void AfxThrowDBException(
RETCODE nRetCode,
CDatabase* pdb,
HSTMT hstmt);
パラメーター
nRetCode
例外がスローされる原因となったエラーの種類を定義する RETCODE 型の値。
pdb
例外が関連付けられているデータ ソース接続を表す CDatabase
オブジェクトへのポインター。
hstmt
例外が関連付けられているステートメント ハンドルを指定する ODBC HSTMT ハンドル。
解説
フレームワークは、ODBC API 関数の呼び出しから ODBC RETCODE を受け取り、予期されるエラーではなく例外的な条件として RETCODE を解釈するときに、 AfxThrowDBException
を呼び出します。 たとえば、ディスク読み取りエラーが原因でデータ アクセス操作が失敗する場合があります。
ODBC で定義された RETCODE 値の詳細については、Windows SDK の第 8 章「状態とエラー情報の取得」を参照してください。 これらのコードの MFC 拡張機能については、クラス CDBExceptionを参照してください。
要件
ヘッダー afx.h
AfxAbort
MFC によって提供される既定の終了関数。
void AfxAbort();
解説
AfxAbort
は、処理できないキャッチされない例外などの致命的なエラーがある場合に、MFC メンバー関数によって内部的に呼び出されます。 回復できない致命的なエラーが発生した場合は、まれに AfxAbort
を呼び出すことができます。
例
CATCH の例を参照してください。
要件
ヘッダー afx.h