我使用普通的C ++ try
和catch
来表示异常。现在我想学习如何使用MFC TRY CATCH。我尝试使用C ++语法将int
变量与MFC关键字一起抛出:
...
var = 0;
TRY
{
if (var == 0)
{
THROW 5;
}
}
CATCH(int a)
{
MessageBoxW(L"Blub", L"blub", NULL);
}
END_CATCH
然而它没有编译。
问题出在哪里?有人可以向我解释一下吗?
或发送一个好的链接,我可以学习MFC TRY CATCH方法。我一直无法找到一个好的解释。
答案 0 :(得分:3)
来自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 ++异常。
答案 1 :(得分:0)
您提供的代码示例中有许多源代码错误。
MFC TRY CATCH THROW不是C ++关键字,而是设计用于C / C ++预处理程序的宏。因此,您需要在MFC宏中使用的语法与在C ++关键字中使用的语法不同。您必须使用预处理器语法。
因此,您的源代码示例应写为:
int var = 0;
TRY
if (var == 0) {
THROW (5);
}
CATCH(int, a)
END_CATCH
但是,正如上面的用户Geek和您对原始帖子的评论一样,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++ topic和Wikipedia topic Microsoft Visual C++以及Version history of VC++, MFC and ATL。 Microsoft的MFC项目的宏伟目标是在Windows API之上提供一个大型而复杂的框架,以提高Windows应用程序开发人员的工作效率。
通过将int
中的CATCH()
更改为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; } }