在 Visual C++ 2019 中引发自定义异常
Throwing a custom exception in Visual C++ 2019
MFC 定义了抛出预定义异常的函数。例如,您使用 ::AfxThrowFileException()
来抛出类型 CFileException
的异常。但是,如果我定义自己的异常 class,它派生自 CException
怎么办?最好的投掷方式是什么?
如果我只是这样做会不会有问题:
if (!m_Settings.IsValid())
throw new CMyException(_T("This operation failed."));
在 Visual Studio 2019 年,上面的代码生成了以下 Intellisense 警告。但是我还没有看到任何使用 make_unique
.
抛出异常的例子
Warning C26409 Avoid calling new and delete explicitly, use std::make_unique instead (r.11).
谁能解释一下,或者让我参考一些最新的文档?
异常处理是其中一个领域,它表明 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++ 异常处理时。
MFC 定义了抛出预定义异常的函数。例如,您使用 ::AfxThrowFileException()
来抛出类型 CFileException
的异常。但是,如果我定义自己的异常 class,它派生自 CException
怎么办?最好的投掷方式是什么?
如果我只是这样做会不会有问题:
if (!m_Settings.IsValid())
throw new CMyException(_T("This operation failed."));
在 Visual Studio 2019 年,上面的代码生成了以下 Intellisense 警告。但是我还没有看到任何使用 make_unique
.
Warning C26409 Avoid calling new and delete explicitly, use std::make_unique instead (r.11).
谁能解释一下,或者让我参考一些最新的文档?
异常处理是其中一个领域,它表明 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++ 异常处理时。