Visual C++中的異常處理淺析(4)

來源:互聯網
上載者:User
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] 下一頁

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.