3

是否有任何优势或用例可以抛出 std::exception(或衍生类型)的其他东西。

例如throw 1;throw "error";

换句话说,为什么 c++ 标准允许它。

4

5 回答 5

5

根据 §15.1 [除外]:

异常处理提供了一种将控制和 信息从线程执行中的点传输到与先前由执行传递的点相关联的异常处理程序的方法。

信息这个词说明了一切,它可以是物体、数字等一切。

标准中没有任何内容说您必须 throw std::exception。换句话说,也许有人想抛出他自己的异常对象。

也许有人想使用异常处理来处理远离正常异常的事情。

于 2013-05-28T14:55:09.873 回答
4

我想不出任何明显的原因为什么派生自的类std::exception通常不会更好。

但是throw 1orthrow "Error"是有效的表达式,它们可能需要更少的“努力”来创建,并且可能在某些情况下这是一个好处。从 的构造函数中抛出exception类型异常exception可能不会很好,所以有一个地方。

然而,这可能更像是一个哲学决定:因为throw可以抛出任何类型的对象,所以允许它不是一个坏主意。你对一种语言的东西施加的限制越多,你对一种语言的可能用途就越限制。

于 2013-05-28T14:54:26.463 回答
3

来自关于 std::exception 的参考资料:

标准::异常

标准库的组件抛出的所有对象都派生自这个类。因此,所有标准异常都可以通过引用捕获此类型来捕获。

例如,通过抛出其他任何东西NuclearPlantException,您可以分别处理您的异常和标准库中的异常。标准库可以抛出std::invalid_argumentstd::bad_alloc(的子类型std::exception),您也可以抛出LossOfCoolant(的子类型NuclearPlantException)。

所以至少有一个优势:将标准库异常与您的异常分开。因为如果你的铀有足够的可用空间,你就不会抛出std::bad_alloc异常,所以任何异常都有明确的来源,可能会使测试和调试更容易。


注意:有关更深入的讨论,请参阅问题我应该从 std::exception 继承吗?.

于 2013-05-28T15:03:20.020 回答
2

是的,可以有优势。

最明显的是,对于(例如,,)what的现有派生词,只处理s 或s 以指定异常的原因。如果您只与说英语的观众打交道,这可能很好,但如果您想使用向不使用英语的人显示错误消息,它可能会很快变得笨拙。std::exceptionstd::logic_errorstd::invalid_argumentstd::stringchar *what

如果您在整个程序中使用(例如)32 位 Unicode 字符串,您通常希望在异常处理中也这样做。在这种情况下,类似于标准中的层次结构,但使用 32 位 Unicode 字符串作为what参数可能很有意义。我想您仍然可以使用std::exception该层次结构的基础,但是可以质疑这样做会获得多少(如果有的话)。

于 2013-05-28T15:08:32.697 回答
0

在 std::exception 甚至 std:: 成为一个想法之前的十年,C++ 中的东西就出现了。出于向后兼容性的原因,它没有被删除。

那些选择不使用 std:: 的人当然喜欢这样,并抛出其他异常,可能是从库提供的某个基类派生的。除非您在客户端代码中处理多个异常层次结构,否则这很好。因此,不完全反对使用 std:: 的新代码(设置 new_handler 以避免 std::bad_alloc)可能会重新调整其异常根类以使用 std::exception 作为基础。

通常建议不要抛出诸如整数或指针之类的非类事物,但在轻量级环境中可能非常有意义——在一个小型嵌入式项目中,启用异常但只抛出一个枚举听起来是明智的。

一般来说,如果语言允许抛出任何可复制的对象,为什么要限制它?即使我们有时间旅行,强制使用特殊的库类也不符合 C++ 的精神。

于 2013-05-28T15:11:37.830 回答