【问题标题】:MFC TRY CATCH versus C++ try catch for exceptions with MFCMFC TRY CATCH 与 C++ 尝试使用 MFC 捕获异常
【发布时间】:2014-11-09 14:58:31
【问题描述】:

我使用普通的 C++ trycatch 处理异常。现在我想学习如何使用 MFC TRY CATCH。我尝试使用带有 MFC 关键字的 C++ 语法抛出 int 变量,如下所示:

...
var = 0;
    TRY
    {
        if (var == 0)
        {
            THROW 5;
        }
    }
    CATCH(int a)
    {
      MessageBoxW(L"Blub", L"blub", NULL);
    }
    END_CATCH

但是它没有编译。

问题出在哪里?谁能给我解释一下?

或者发送一个很好的链接,我可以在那里学习 MFC TRY CATCH 方法。我一直找不到好的解释。

【问题讨论】:

  • 使用 MFC 宏只能捕获 CException*。该宏已经过时了,不要使用它。
  • Here 是微软建议将 MFC 宏转换为普通 c++ try/catch 的页面。

标签: c++ mfc


【解决方案1】:

来自 MSDN Exceptions: Converting from MFC Exception Macros

您可能不需要转换现有代码,尽管您应该 注意 MFC 中宏实现之间的差异 3.0 版和早期版本中的实现。这些 代码行为的差异和后续变化在 Exceptions: Changes to Exception Macros in Version 3.0。校长 转换的优点是:

  • 使用 C++ 异常处理关键字的代码编译为稍小的 .EXE 或 .DLL。

  • C++ 异常处理关键字更加通用:它们可以处理任何可以复制的数据类型的异常(int、float、 char 等),而宏只处理类的异常 CException 及其派生类。

宏和关键字的主要区别在于代码 使用宏“自动”删除捕获的异常时 异常超出范围。使用关键字的代码没有,所以你 必须显式删除捕获的异常。有关详细信息,请参阅 文章Exceptions: Catching and Deleting Exceptions

MFC 只能捕获 CException 或派生类,如果要处理其他数据类型,请使用 c++ 异常。

【讨论】:

    【解决方案2】:

    您提供的代码示例中有许多源代码错误。

    MFC TRY CATCH THROW 不是 C++ 关键字,而是设计用于 C/C++ 预处理器的宏。因此,您需要与 MFC 宏一起使用的语法与 C++ 关键字不同。您必须使用预处理器语法。

    所以你的源代码示例应该写成:

    int var = 0;
    
    TRY
        if (var == 0) {
            THROW (5);
        }
    CATCH(int, a)
    END_CATCH
    

    但是,作为上面的用户 Geek 以及您原始帖子的 cmets,MFC TRY CATCH THROW 宏旨在与 MFC CException 类一起使用,而不像 C++ 异常那样更通用目的和更方便。

    使用上述半更正的源代码,您将看到编译器错误,例如:

    error C2227: left of '->IsKindOf' must point to class/struct/union/generic type
    error C2039: 'GetThisClass' : is not a member of '`global namespace''
    error C2146: syntax error : missing ')' before identifier 'GetThisClass'
    error C2440: '=' : cannot convert from 'int *' to 'CException *'
    

    这些错误是由于没有使用CException 类或从CException 派生的类。一般来说,MFC 源代码库中有很多隐藏的管道,虽然它们提供了相当多的功能,但也可能会受到限制。

    MFC 于 1990 年代初在 1998 年发布第一个 C++ 标准之前首次发布。因此,Visual Studio 和 MFC 处于第一个 C++ 标准化的移动目标的最前沿。请参阅 History section of the Wikipedia C++ topicWikipedia topic Microsoft Visual C++ 以及 Version history of VC++, MFC and ATL。 Microsoft 的 MFC 项目有一个雄心勃勃的目标,即在 Windows API 之上提供一个大型而复杂的框架,以提高 Windows 应用程序开发人员的工作效率。

    通过将CATCH() 中的int 更改为CException,现在将编译源代码。

    查看 MFC 包含文件 afx.h,您可以看到这些宏的定义位置。 请注意说这些仅为向后兼容而提供的注释。

    /////////////////////////////////////////////////////////////////////////////
    // Exception macros using try, catch and throw
    //  (for backward compatibility to previous versions of MFC)
    
    #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; } }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-12-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      相关资源
      最近更新 更多