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++的方式。

  • 相关阅读:
    POJ3320 Jessica's Reading Problem
    POJ3320 Jessica's Reading Problem
    CodeForces 813B The Golden Age
    CodeForces 813B The Golden Age
    An impassioned circulation of affection CodeForces
    An impassioned circulation of affection CodeForces
    Codeforces Round #444 (Div. 2) B. Cubes for Masha
    2013=7=21 进制转换
    2013=7=15
    2013=7=14
  • 原文地址:https://www.cnblogs.com/renyuan/p/3430963.html
Copyright © 2011-2022 走看看