zoukankan      html  css  js  c++  java
  • MFC异常处理的问题

                                                 参考文献:http://technet.microsoft.com/zh-cn/library/t078xe4f(v=vs.85).aspx

    MFC中异常处理的语法和语义构建在标准C++异常处理语法和语义的基础之上,其解决方案为:MFC异常处理 = MFC 异常处理类 + 宏

    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 再次抛出最近一次捕获的异常。

    2 MFC 异常处理类

    MFC较好地将异常封装到CException类及其派生类中,自成体系,下表给出了MFC 提供的预定义异常:

    异常类   含义 
    CMemoryException   内存不足 
    CFileException 文件异常 
    CArchiveException   存档/序列化异常 
    CNotSupportedException   响应对不支持服务的请求 
    CResourceException Windows 资源分配异常 
    CDaoException 数据库异常(DAO 类) 
    CDBException   数据库异常(ODBC 类) 
    COleException OLE 异常 
    COleDispatchException   调度(自动化)异常 
    CUserException   用消息框警告用户然后引发一般 CException 的异常 

    标准C++的异常处理可以处理任意类型的异常,而MFC 宏则只能处理CException 的派生类型,下面我们看一个CFileException的使用例子:

    CODE:  
    #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 " << endl; 
     }
     END_CATCH 
    }

      在这个程序中,如果D盘根目录下不存在"1.TXT"这个文件,将抛出CFileException异常,而且错误原因成员变量m_cause被设置为fileNotFound,我们以CATCH( CFileException, e )就可以捕获到。错误原因被定义为CFileException中的枚举(enum),如下:

    CODE:
    enum {
     none,
     generic,
     fileNotFound,
     badPath,
     tooManyOpenFiles,
     accessDenied,
     invalidFile,
     removeCurrentDir,
     directoryFull,
     badSeek,
     hardIO,
     sharingViolation,
     lockViolation,
     diskFull,
     endOfFile
    };

      我们在使用MFC相关类时,MFC会自动抛出异常,当然我们也可以自行在程序中利用AfxThrowXXXException()抛出各种类型的异常,其中的XXX与前文的MFC异常类表对应。我们看AfxThrowFileException的例子:

    CODE:  
    #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 " << endl; 
     }
     END_CATCH 
    }

      在此程序中,我们在TRY块自行利用MFC提供的全局函数AfxThrowFileException抛出了CFileException异常,其后在CATCH块抓住了这个异常。

      MFC建议不再使用TRY、CATCH和THROW宏,而是直接使用标准C++的方式。

  • 相关阅读:
    Mix and Build(简单DP)
    Is It A Tree?(并查集)
    Paths on a Grid(简单组合数学)
    Code(组合数学)
    Round Numbers(组合数学)
    Inviting Friends(二分+背包)
    Communication System(dp)
    Human Gene Functions
    Pearls
    敌兵布阵(线段树HDU 1166)
  • 原文地址:https://www.cnblogs.com/renyuan/p/3430963.html
Copyright © 2011-2022 走看看