C++ 异常和来自 std::exception 的继承

Posted

技术标签:

【中文标题】C++ 异常和来自 std::exception 的继承【英文标题】:C++ Exceptions and Inheritance from std::exception 【发布时间】:2011-02-03 21:58:16 【问题描述】:

鉴于此示例代码:

#include <iostream>
#include <stdexcept>

class my_exception_t : std::exception

public:
    explicit my_exception_t()
     

    virtual const char* what() const throw()
     return "Hello, world!"; 
;

int main()

    try
         throw my_exception_t(); 
    catch (const std::exception& error)
         std::cerr << "Exception: " << error.what() << std::endl; 
    catch (...)
         std::cerr << "Exception: unknown" << std::endl; 

    return 0;

我得到以下输出:

Exception: unknown

然而,简单地从std::exceptionpublic继承my_exception_t,我得到以下输出:

Exception: Hello, world!

有人可以向我解释为什么在这种情况下继承类型很重要吗?标准中参考的奖励积分。

【问题讨论】:

【参考方案1】:

谁能解释一下为什么 继承的类型很重要 这个案例?奖励积分 参考标准。

继承的类型无关紧要。重要的是您有一个可用于其中一种捕获类型的可访问转换。碰巧的是,由于它不是公共继承,因此没有公共可访问的转换。


说明:

您可以在此处看到相同的行为:

class B

;

class C1 : B

;

class C2 : public B

;

int main(int argc, char** argv)

    B& b1 = C1();//Compiling error due to conversion exists but is inaccessible
    B& b2 = C2();//OK
    return 0;

一个抛出的异常只有在以下情况下才会被 catch 块捕获:

    catch 块有一个匹配的类型,或者 catch 块用于具有可访问转换的类型 catch 块是一个 catch(...)

【讨论】:

my_exception_t 在这两种情况下都派生自 std::exception @fbrereto:感谢您的澄清,我在回答中解释了请重新阅读。【参考方案2】:

当您私有继承时,您不能转换为或以其他方式访问该类之外的该基类。既然你从标准中要求了一些东西:

§11.2/4: 如果基类的一个发明的公共成员是可访问的,则称该基类是可访问的。如果基类是可访问的,则可以将指向派生类的指针隐式转换为指向该基类的指针(4.10、4.11)。

简单地说,对于类之外的任何东西,就像你从未从std::exception 继承一样,因为它是私有的。因此,它不会被std::exception&amp; 子句捕获,因为不存在转换。

【讨论】:

以上是关于C++ 异常和来自 std::exception 的继承的主要内容,如果未能解决你的问题,请参考以下文章

我可以/我应该使用 std::exception 进行常规错误处理吗?

如何捕获 I/O 异常(确切地说是 I/O,而不是 std::exception)

区别:std::runtime_error 与 std::exception()

std::any 由 std::exception_ptr

在抛出std :: exception的实例后终止调用

error: no matching function for call to 'std::exception:exception(const char[16])'