抛出C ++异常时要抛出什么?

时间:2012-02-27 20:56:15

标签: c++ exception

这可能是一个愚蠢的问题,但在C ++中,当我想抛出异常时......我该扔什么?

我应该抛出std :: exception,还是标准库保留的?或者我应该抛出一个字符串或int?或者我应该抛出我觉得合适的东西?

5 个答案:

答案 0 :(得分:31)

抛出一个源自std::exception的类;如果您#include <stdexcept>,则可以从多个ready-made, useful派生类中选择。

std::exception派生可让您的处理程序遵循可识别的样式,因为您始终可以使用.what()来获取文本消息。不要抛出原始类型,因为它们没有语义信息。

答案 1 :(得分:8)

通常人们不会直接抛出std :: exception,原因很简单,因为它不存储任何错误消息。什么方法不会返回任何东西。我有时会对此感到困惑,因为MSVC为std :: exception中的一个接受字符串的参数化构造函数提供了非标准扩展。

您可以在现有的异常类中进行选择,例如std :: runtime_exception或定义您自己的异常类。这有些主观,但我建议将异常类的数量保持在最低限度,因为RAII可以消除很多需要拥有多个代码分支并捕获不同异常类型的块。通常,消息与符合RAII的代码相结合,足以从任何异常中优雅地恢复。

最后,为了类似的原因,我建议你从std :: exception继承的所有异常。如果可以避免,则不希望不同的异常类型使用许多不同的catch块来丢弃代码。尽可能地解决问题。

答案 2 :(得分:2)

抛出从std::exception派生的内容的主要例外是,如果您正在使用某个具有自己的异常层次结构的框架(例如,MFC)。在这种情况下,您通常希望从其层次结构中的适当位置派生。

请注意,我并没有特别尝试将MFC作为干净异常处理(或一般的干净设计)的示例,而只是包含异常层次结构的框架的示例。当您使用已定义异常层次结构的框架时,通常最好不要使用它。

换句话说,与C ++中的首选项不同,通常认为异常应该是具有单个根的单个单一层次结构。对于标准库,单个根是std::exception,但是其他框架有替代方案,如果它们提供了一个,您通常希望将其纳入其中。

答案 3 :(得分:1)

与java不同,你可以抛出你想要的任何东西(int, string, MyClass, ...)。但听听Kerrek的话。 :)

答案 4 :(得分:0)

通常你会想像其他人所说的那样抛出std::exception派生的一个例外。

有时我会抛出其他类型,但只有当它被捕获在同一个块中并且该值在该上下文中是有用的。