例外処理

プログラムを実行すると、"例外" と呼ばれる異常な条件やエラーが多数発生する可能性があります。 これには、メモリ不足、リソース割り当てエラー、およびファイルの検索エラーが含まれる場合があります。

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 つの例外クラスとCDaoExceptionCDBException例外の種類をサポートするグローバル関数が用意されています。

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

関連項目

マクロとグローバル
CException クラス
CInvalidArgException クラス