Share via


例外狀況處理

當程式執行時,可能會發生一些稱為「例外狀況」的異常狀況和錯誤。 這可能包括記憶體不足、資源配置錯誤,以及找不到檔案。

Microsoft Foundation Class Library 會使用例外狀況處理配置,此配置會在 ANSI 標準委員會針對 C++ 提出的例外狀況處理配置之後進行密切模型化。 呼叫可能會遇到異常狀況的函式之前,必須先設定例外狀況處理常式。 如果函式遇到異常狀況,則會擲回例外狀況,並將控制項傳遞至例外狀況處理常式。

Microsoft Foundation Class Library 隨附的數個宏會設定例外狀況處理常式。 如有需要,其他一些全域函式有助於擲回特殊例外狀況並終止程式。 這些宏和全域函式分為下列類別:

  • 例外狀況宏,其會建構例外狀況處理常式。

  • 例外狀況擲回函式),其會產生特定類型的例外狀況。

  • 終止函式,導致程式終止。

如需範例和詳細資訊,請參閱例外狀況 一文

例外狀況宏

名稱 描述
嘗試 指定程式碼區塊以進行例外狀況處理。
抓住 指定程式碼區塊,以攔截上述 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 例外狀況的例外狀況擲回函式:

OLE 例外狀況函式

名稱 描述
AfxThrowOleDispatchException 在 OLE 自動化函式內擲回例外狀況。
AfxThrowOleException 擲回 OLE 例外狀況。

為了支援資料庫例外狀況,資料庫類別會提供兩個例外狀況類別, CDBException 以及 CDaoException 和 全域函式,以支援例外狀況類型:

DAO 例外狀況函式

名稱 描述
AfxThrowDAOException 從您自己的程式碼擲 回 CDaoException
AfxThrowDBException 從您自己的程式碼擲回 CDBException

MFC 提供下列終止函式:

終止函式

名稱 描述
AfxAbort 呼叫 以在發生嚴重錯誤時終止應用程式。

TRY

設定 TRY 區塊。

TRY

備註

TRY 區塊會識別可能會擲回例外狀況的程式碼區塊。 這些例外狀況會在下列 CATCH AND_CATCH 區塊中處理。 允許遞迴:例外狀況可能會傳遞至外部 TRY 區塊,方法是忽略它們或使用THROW_LAST宏。 使用 END_CATCH 或 END_CATCH_ALL 宏結束 TRY 區塊。

如需詳細資訊,請參閱例外狀況 一文

範例

請參閱 CATCH 範例。

需求

標頭:afx.h

抓住

定義程式碼區塊,以攔截在上述 TRY 區塊中擲回的第一個例外狀況類型。

CATCH(exception_class, exception_object_pointer_name)

參數

exception_class
指定要測試的例外狀況類型。 如需標準例外狀況類別的清單,請參閱 CException 類別

exception_object_pointer_name
指定將由巨集建立的例外狀況物件指標的名稱。 您可以使用指標名稱來存取 CATCH 區塊內的例外狀況 物件。 會為您宣告這個變數。

備註

處理例外狀況的程式碼可以查閱例外狀況物件,如果可行,取得關於例外狀況特定原因的詳細資訊。 叫用THROW_LAST宏,將處理移至下一個外部例外狀況框架。 使用 END_CATCH 宏結束 TRY 區塊。

如果 exception_class 是 類別 CException ,則會攔截所有例外狀況類型。 您可以使用 CObject::IsKindOf 成員函式來判斷擲回的特定例外狀況。 擷取數種例外狀況的較佳方式是使用循序 AND_CATCH 語句,每個語句都有不同的例外狀況類型。

例外狀況物件指標是由宏所建立。 您不需要自行宣告。

注意

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 區塊。

注意

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 宏來擷取一個例外狀況類型,然後AND_CATCH宏來攔截每個後續類型。 使用 END_CATCH 宏結束 TRY 區塊。

處理例外狀況的程式碼可以查閱例外狀況物件,如果可行,取得關於例外狀況特定原因的詳細資訊。 呼叫 AND_CATCH 區塊內的 THROW_LAST 宏,將處理移轉至下一個外部例外狀況框架。 AND_CATCH 會標示上述 CATCH AND_CATCH 區塊的結尾。

注意

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 宏來攔截一個例外狀況類型,然後AND_CATCH_ALL宏來攔截所有其他後續類型。 如果您使用 AND_CATCH_ALL,請使用 END_CATCH_ALL 宏結束 TRY 區塊。

處理例外狀況的程式碼可以查閱例外狀況物件,如果可行,取得關於例外狀況特定原因的詳細資訊。 呼叫 AND_CATCH_ALL 區塊內的 THROW_LAST 宏,將處理移轉至下一個外部例外狀況框架。 AND_CATCH_ALL會標示上述 CATCH AND_CATCH_ALL 區塊的結尾。

注意

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 Class Library 模組。

如需詳細資訊,請參閱例外狀況 一文

需求

標頭 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 Automation 函式內擲回例外狀況。

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 Automation 用戶端應用程式) 來加以顯示。

範例

// 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 中 定義的其中一個錯誤,但您不在意 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 控制碼,指定與例外狀況相關聯的語句控制碼。

備註

AfxThrowDBException架構會在從對 ODBC API 函式的呼叫收到 ODBC RETCODE 時呼叫,並將 RETCODE 解譯為例外狀況,而不是預期的錯誤。 例如,資料存取作業可能會因為磁片讀取錯誤而失敗。

如需 ODBC 所定義 RETCODE 值的相關資訊,請參閱 Windows SDK 中的第 8 章。 如需這些程式碼 MFC 延伸模組的相關資訊,請參閱 CDBException 類別

需求

標頭 afx.h

AfxAbort

MFC 提供的預設終止函式。

void  AfxAbort();

備註

AfxAbort 發生嚴重錯誤時,MFC 成員函式會在內部呼叫,例如無法處理的未攔截例外狀況。 當您遇到無法復原的嚴重錯誤時,可以在罕見的情況下呼叫 AfxAbort

範例

請參閱 CATCH 範例。

需求

標頭 afx.h

另請參閱

宏和全域
CException 類別
CInvalidArgException 類別