在Visual C ++ 2019中引发自定义异常

时间:2019-04-09 19:55:29

标签: visual-studio exception visual-c++ mfc

MFC定义了引发预定义异常的函数。例如,您使用::AfxThrowFileException()引发类型CFileException的异常。但是,如果我定义了自己的异常类,该类是从CException派生的,该怎么办?扔它的首选方式是什么?

如果我只是这样做,就会有问题吗

if (!m_Settings.IsValid())
    throw new CMyException(_T("This operation failed."));

在Visual Studio 2019中,上面的代码生成以下Intellisense警告。但是我还没有看到任何使用make_unique引发异常的示例。

  

警告C26409避免显式调用new和delete,而应使用std :: make_unique(r.11)。

任何人都可以解释一下,还是请我参考一些最新文档?

1 个答案:

答案 0 :(得分:0)

异常处理是它表明MFC早于C ++的那些领域之一。由于C ++异常是C ++标准的较晚添加,因此MFC已经决定了其异常处理策略:

  • 在免费存储区上分配异常对象。
  • 通过指针投掷。
  • 通过指针捕获。
  • 释放异常对象相关的资源需要任何处理异常的catch子句。

相比之下,处理C ++异常的惯用方式遵循以下准则:

  • 根据值自动存储持续时间来抛出异常对象。
  • 通过(const)引用捕获。
  • 资源清理是自动处理的。

使用MFC可以使用以上两种方法之一。 MFC提供了异常宏,以帮助使前者更不易出错,尽管没有严格要求使用它们。实际上,exception macros in version 3.0已经在后台几乎完全使用C ++异常处理。

在MFC中引发自定义异常的正确方法取决于调用它的代码。如果该代码使用的是MFC异常宏,则需要将指针指向动态分配的异常对象,例如

throw new CMyException(_T("This operation failed."));

THROW( (CException*) new CMyException(_T("This operation failed.")) );

并忽略编译器警告。这是必需的,因为CATCH宏将始终扩展为与指针类型匹配的catch子句。

另一方面,如果调用代码使用C ++异常处理,则按值或指针进行投掷都没有问题,例如

throw CMyException(_T("This operation failed."));
// or
throw new CMyException(_T("This operation failed."));

并通过const引用或指针捕获:

catch( CException const& ) {
    // no cleanup required
}
// or
catch( CException* e ) {
    // manual cleanup still required, unless the exception is re-thrown
    e->Delete();
}

在前面的代码段中,还允许同时使用两个catch子句,从而允许您设置调用代码以处理按代码中的值引发自定义异常以及调用MFC提供的混合操作产生由指针抛出的动态分配的异常对象的代码。

甚至可以在某种程度上混合使用C ++异常处理和MFC异常宏(Exceptions: Using MFC Macros and C++ Exceptions)。提供的信息仅出于完整性考虑。不建议混合使用C ++异常和MFC异常宏,除非有充分的理由这样做,例如在将现有代码从MFC异常宏逐步过渡到C ++异常处理时。