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::exception
public
继承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&
子句捕获,因为不存在转换。
【讨论】:
以上是关于C++ 异常和来自 std::exception 的继承的主要内容,如果未能解决你的问题,请参考以下文章
我可以/我应该使用 std::exception 进行常规错误处理吗?
如何捕获 I/O 异常(确切地说是 I/O,而不是 std::exception)
区别:std::runtime_error 与 std::exception()
error: no matching function for call to 'std::exception:exception(const char[16])'