私有继承自 std::runtime_error 的类不会被捕获为 std::exception

Class that is privately inherited from std::runtime_error is not caught as std::exception

本文关键字:std exception error 继承 runtime      更新时间:2023-10-16

这一切都在这个例子中

class MyException: std::runtime_error // note, there is no public keyword in inheritance
{
public:
   MyException(const std::string & x)
      : std::runtime_error(x)
   {}
};

int main( )
{
   try
   {
      throw MyException("foo");
   }
   catch (std::exception & e )
   {
      std::cout << "catched std exception: " << e.what() << std::endl;
   }
   catch (...)
   {
      std::cout << "catched ... " << std::endl;
   }
}

它在标准输出字符串上写着">捕获..."。但是,如果我将继承更改为公共class MyException : public std::runtime_error,它按预期工作(对我来说(并写">捕获的 std 异常:foo">

C++标准的哪一部分需要这种行为?为什么呢?在什么情况下,这种行为可能是有用的?

这是有意义的,并且与重载解析的规则一致。在MyException之外,你的班级不是std::exception。您应该将私有继承视为实现细节(具有非常高的耦合性(。

它在 15.3 处理异常中:

处理程序是类型 E 的异常对象的匹配项,如果

— 处理程序的类型为 cv T 或 cv T& 和 E 和 T 是同一类型 (忽略顶级简历限定符(,或

— 处理程序的类型为 CV T 或 cv T& and T 是 E 的明确公共基础类,或

— 处理程序的类型为 cv1 T* cv2,E 是指针类型,可以是 通过其中一个或两个转换为处理程序的类型 - 标准 指针转换 (4.10( 不涉及指向指针的转换 私有或受保护或不明确的类 — 资格转换

— 处理程序是指向成员类型的指针或指针,E 是 std::nullptr_t。

(强调我的(

因为私有继承不允许您将Derived*/Derived&视为Base*/Base&。这意味着您不能将Derived*放在预期Base*的地方。

实际上,当您只想实现某个类而不接受其接口时,将使用私有继承...

它是私有继承,MyException不能转换为std::runtime_error