例外狀況處理
當程式執行時,可能會發生一些稱為「例外狀況」的異常狀況和錯誤。 這可能包括記憶體不足、資源配置錯誤,以及找不到檔案。
Microsoft基礎類庫會使用例外狀況處理配置,在 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