【问题标题】:Is there any advantages to throw other thing that a std::exception( or derivatives types)抛出 std::exception( 或衍生类型) 的其他东西有什么好处吗
【发布时间】:2013-05-28 14:44:27
【问题描述】:

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

例如throw 1;throw "error";

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

【问题讨论】:

标签: c++ exception-handling


【解决方案1】:

根据 §15.1 [除外]:

异常处理提供了一种转移控制和 从线程执行到异常的信息 与执行之前传递的点相关联的处理程序。

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

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

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 其实我写错了,现在已经编辑了。但是,是的,这里有各种不同选项的论据。
    【解决方案3】:

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

    std::exception

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

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

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


    注意:更深入的讨论见问题Should I inherit from std::exception?

    【讨论】:

      【解决方案4】:

      是的,可以有优势。

      最明显的是std::exception的现有派生类的what(例如std::logic_errorstd::invalid_argument)只处理std::strings或char *s来指定异常的原因。如果您只与说英语的观众打交道,这可能没问题,但如果您想使用 what 向不使用英语的人显示错误消息,它可能会很快变得笨拙。

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

      【讨论】:

        【解决方案5】:

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

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

        通常建议不要使用 int 或指针等非类的东西,但在轻量级的环境中是完全合理的——在一个小型嵌入式项目中启用异常但只抛出一个 enum 听起来是明智的。

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

        【讨论】:

          猜你喜欢
          • 2012-12-06
          • 2012-06-12
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-18
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多