为什么 C++ 允许抛出任何东西?

GPh*_*ilo 5 c++ exception-handling

我刚看到这个问题及其相关答案。考虑到我以前从未遇到过这种使用throws 的方式,我很惊讶地发现这甚至是可能的。

  • 允许(几乎)任何东西被抛出和捕获背后的逻辑是什么?
  • 是否使用了超出异常/错误信号的 throw-catch 语法?如果是这样,这是否被认为是不好的做法,还是有我从未意识到的“常见”用法?

Lig*_*ica 4

如果不进行猜测,这个问题很难回答,但 Bjarne 1998 年的论文“C++ 编程语言概述”在描述异常处理时使用任意类型,并建议创建所述类型的层次结构以方便/语义。看来他exception一开始并没有为这些中的任何一个设定“基类”。

拥有标准层次结构(基于 )的概念可能std::exception最初是作为“添加”出现的,这是一种处理 Bjarne 建议的异常使用的便捷方法,而不是每个人使用异常所应基于的构建块。当代的做法是从中得出所有例外,这std::exception似乎是后来出现的。

如今,我想不出有什么理由不这样做,如果没有其他原因,除了使用你的代码的人可能会期望顶层catch (const std::exception&)吸收任何有用的东西。不过,为了以防万一,我也倾向于添加一个catch (...)main

更实际地说,如果不是这种情况,则必须有附加规则限制throw仅对派生于 的类型的表达式“有效” std::exception,这似乎没有任何现实世界的好处足以证明附加规则的合理性。不管你信不信,C++ 就“为什么我们没有这样那样的规则”这个问题而言,来自于一个极简主义的地方,尽管显然它的膨胀在这么多年之后似乎与此相矛盾。

throw我怀疑这与用于非例外的事情有什么关系,因为这一直被认为是不好的做法。Bjarne 描述此功能的方式是:

异常用于将控制从检测到错误的地方转移到某个表示有兴趣处理此类错误的调用者。显然,这种机制应该仅用于无法本地处理的错误。[..] 异常可用于使错误处理更加程式化和规则化。

因此很明显,至少最初的设计意图(这仍然是常识)是仅在异常/错误情况下使用异常。