3.MFC異常處理
MFC中異常處理的文法和語義構建在標準C++異常處理文法和語義的基礎之上,其解決方案為:
MFC異常處理 = MFC 異常處理類 + 宏
3.1宏
MFC定義了TRY、CATCH(及AND_CATCH、END_CATCH)和THROW(及THROW_LAST)等用於異常處理的宏,其本質上也是標準C++的try、catch和throw的進一步強化,由這些宏的定義可知:
| #ifndef _AFX_OLD_EXCEPTIONS #define TRY { AFX_EXCEPTION_LINK _afxExceptionLink; try { #define CATCH(class, e) } catch (class* e) \ { ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \ _afxExceptionLink.m_pException = e; #define AND_CATCH(class, e) } catch (class* e) \ { ASSERT(e->IsKindOf(RUNTIME_CLASS(class))); \ _afxExceptionLink.m_pException = e; #define END_CATCH } } #define THROW(e) throw e #define THROW_LAST() (AfxThrowLastCleanup(), throw) // Advanced macros for smaller code #define CATCH_ALL(e) } catch (CException* e) \ { { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \ _afxExceptionLink.m_pException = e; #define AND_CATCH_ALL(e) } catch (CException* e) \ { { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \ _afxExceptionLink.m_pException = e; #define END_CATCH_ALL } } } #define END_TRY } catch (CException* e) \ { ASSERT(e->IsKindOf(RUNTIME_CLASS(CException))); \ _afxExceptionLink.m_pException = e; } } |
這些宏在使用文法上,有如下特點:
(1)用TRY 塊包含可能產生異常的代碼;
(2)用CATCH塊檢測並處理異常。要注意的是,CATCH塊捕獲到的不是異常對象,而是指向異常對象的指標。此外,MFC靠動態類型來辨別異常對象;
(3)可以在一個TRY 塊上捆綁多個異常處理捕獲塊,第一次捕獲使用宏CATCH,以後的使用AND_CATCH,而END_CATCH則用來結束異常捕獲隊列;
(4)在例外處理常式內部,可以用THROW_LAST 再次拋出最近一次捕獲的異常。
3.2 MFC 異常處理類
MFC較好地將異常封裝到CException類及其衍生類別中,自成體系,下表給出了MFC 提供的預定義異常:
| 異常類 |
含義 |
| CMemoryException |
記憶體不足 |
| CFileException |
檔案異常 |
| CArchiveException |
存檔/序列化異常 |
| CNotSupportedException |
響應對不支援服務的請求 |
| CResourceException |
Windows 資源分派異常 |
| CDaoException |
資料庫異常(DAO 類) |
| CDBException |
資料庫異常(ODBC 類) |
| COleException |
OLE 異常 |
| COleDispatchException |
調度(自動化)異常 |
| CUserException |
用訊息框警告使用者然後引發一般 CException 的異常 |
標準C++的異常處理可以處理任意類型的異常,而3.1節的MFC 宏則只能處理CException 的衍生類別型,下面我們看一個CFileException的使用例子:
#include <iostream.h> #include "afxwin.h" int main() { TRY { CFile f( "d:\\1.txt", CFile::modeWrite ); } CATCH( CFileException, e ) { if( e->m_cause == CFileException::fileNotFound ) cout << "ERROR: File not found\n" << endl; } END_CATCH } |
在這個程式中,如果D盤根目錄下不存在"1.TXT"這個檔案,將拋出CFileException異常,而且錯誤原因成員變數m_cause被設定為fileNotFound,我們以CATCH( CFileException, e )就可以捕獲到。錯誤原因被定義為CFileException中的枚舉(enum),如下:
enum { none, generic, fileNotFound, badPath, tooManyOpenFiles, accessDenied, invalidFile, removeCurrentDir, directoryFull, badSeek, hardIO, sharingViolation, lockViolation, diskFull, endOfFile }; |
我們在使用MFC相關類時,MFC會自動拋出異常,當然我們也可以自行在程式中利用AfxThrowXXXException()拋出各種類型的異常,其中的XXX與前文的MFC異常類表對應。我們看AfxThrowFileException的例子:
#include <iostream.h> #include "afxwin.h" int main() { TRY { AfxThrowFileException(CFileException::fileNotFound); } CATCH( CFileException, e ) { if( e->m_cause == CFileException::fileNotFound ) cout << "ERROR: File not found\n" << endl; } END_CATCH } |
在此程式中,我們在TRY塊自行利用MFC提供的全域函數AfxThrowFileException拋出了CFileException異常,其後在CATCH塊抓住了這個異常。
MFC建議不再使用TRY、CATCH和THROW宏,而是直接使用標準C++的方式。
上一頁 [1] [2] [3] [4] [5] 下一頁