我创建了一个派生自 std::exception 的自定义异常类。
#include <iostream>
class Exception : std::exception {
public:
const char* what() const noexcept override {
return "test";
}
};
int main() {
try {
throw Exception();
} catch (std::exception& e) {
std::cout << e.what() << std::endl;
}
}
此程序在 Ubuntu 上由
g++ -stdc++=17
编译时,会导致异常不会被 catch
块捕获,即使通过引用捕获也应该捕获派生异常。它调用 std::terminate
,即使它发生在通过引用捕获其基类的 try
块中。如果 Exception
继承自 std::runtime_error
并将 "test"
传递给其自己的构造函数中的 std::runtime_error
构造函数,也会发生同样的情况。通常,解决方案是仅使用 Exception
进行捕获,但在我的原始代码中,我需要捕获不同类型的异常,所有这些异常都继承自 std::exception
。为什么会出现这种情况?通过引用基数进行捕获不起作用吗?如何使用一个 catch 块捕获源自 std::exception
的所有异常?
在定义
class
期间从基类继承时,继承的默认访问修饰符是 private
。这意味着以下两个定义是等效的:
class derived : base { /* ... */ };
class derived : private base { /* ... */ };
该语言不允许1您从私有基2引用派生类。例如,以下代码无法编译:
int main()
{
derived d;
base& b = d; // <== compilation error
}
error: 'base' is an inaccessible base of 'derived' base& b = d; ^
这就是你的
catch
块无法处理Exception
的原因。将您的继承更改为 public
...
class Exception : public std::exception
...您的原始代码将起作用。
1 请参阅 [dcl.init.ref] 和 [conv.ptr]。
2 除非你在
derived
本身的范围内。请参阅 wandbox.org 上的这个 现场示例。
您需要公开源自
std::exception
class Exception : public std::exception
那么你的输出是
test
有关此主题的更多详细信息,请参阅私有继承、公共继承和受保护继承之间的区别。