例外狀況處理
當程式執行時,可能會發生一些稱為「例外狀況」的異常狀況和錯誤。 這可能包括記憶體不足、資源配置錯誤,以及找不到檔案。
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
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應