gpt4 book ai didi

c++ - 为什么 std::logic_error 实际上不是从 std::exception 继承的?

转载 作者:搜寻专家 更新时间:2023-10-31 01:33:51 25 4
gpt4 key购买 nike

我正在尝试实现自定义异常层次结构并允许适当的 std::* 被代码捕获。

class my_exception : public virtual std::exception {
};
class my_bad_widget_state : public virtual my_exception, public virtual std::logic_error {
public: my_bad_widget_state() : std::logic_error("widget oops") {}
};

显然 my_bad_widget_state 是一个 my_exception,也是一个 std::logic_error,但是编译器拒绝了这段代码,因为 std::exception 在继承异常时没有说 virtual,所以存在歧义。编译器是正确的,但我认为标准库可能是错误的,或者?

编辑:显然 my_bad_widget_state 是一个 my_exception 所以一个 logic_error 也是一个 std::exception,当 my_bad_widget_state 被抛出时 std::exception 没有被捕获。

编辑:我很想知道标准库是否是出于我目前无法理解的特定原因(如果是,那是什么原因)以这种方式设计的,或者它是否是某种疏忽。我的研究表明,很多人似乎认为这是一个问题,但我没有找到任何继承不应该是虚拟的理由。

Q1:为什么标准库中的继承不是virtual?

Q2:如何正确实现? [已回复]

最佳答案

[W]hy is the inheritance [w.r.t. exceptions] in the standard library not virtual?

简单地说,标准异常层次结构中的多重继承不打算得到支持。它不是虚拟派生的,实际上这就是它的意思。

相比之下,在标准库中哪里支持这个? I/O streams是第一个想到的例子。特别是 basic_ios 的使用一直沿层次结构向下到 basic_iostream。在这种情况下,目的是通过虚拟派生基来支持多重继承,避免“菱形继承(钻石问题)”。

那么这是为什么呢,std::exception应该如何使用呢?

std::exception有多个派生自它的异常,特别注意 std::logic_errorstd::runtime_error .标准库已经为我们提供了一个用于异常分类和组织的板模式,即;

class logic_error;

Defines a type of object to be thrown as exception. It reports errors that are a consequence of faulty logic within the program such as violating logical preconditions or class invariants and may be preventable.

class runtime_error;

Defines a type of object to be thrown as exception. It reports errors that are due to events beyond the scope of the program and can not be easily predicted.

当然,这不是唯一的两个,但它们捕获了大量其他标准库异常,并且是它们的基础。

异常层次结构的根在哪里?

  • 如果您希望使用标准库异常层次结构,最好选择一个点来扩展层次结构并从该点开始工作。因此,如果需要自定义根异常,则将 std::exception 作为基类,并从该自定义基类中派生更多自定义异常。

  • 如果自定义异常可分为运行时错误和逻辑错误,则从该级别开始派生自定义异常层次结构。

使用 Root 于标准库异常中某处的自定义异常层次结构通常是个好主意。根应该在什么时候取决于代码的实际预期用途。 See here for a broader Q&A on this .

boost 异常呢?

Boost uses virtual inheritance ,他们这样做是为了准确支持标准库不支持的多重继承。它还支持标准库中没有的一些附加功能。

也就是说,boost 仍然使用 std::exception 作为基类。

最终,这将成为基于您希望在层次结构中支持的继承结构的设计决策。

关于c++ - 为什么 std::logic_error 实际上不是从 std::exception 继承的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40601894/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com