我创建了一个派生自 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 block 捕获,即使按引用捕获也应该捕获派生异常。它调用 std::terminate,即使它发生在通过引用捕获其基类的 try block 中。如果 Exception 继承自 std::runtime_error 并在其自己的构造函数中将“test”传递给 std::runtime_error 构造函数,则会发生同样的事情。通常解决方案是只使用 Exception 进行捕获,但在我的原始代码中我需要捕获不同类型的异常,所有这些异常都继承自 std::exception。为什么会这样?引用 base 捕获不起作用吗?如何使用一个 catch block 捕获从 std::exception 派生的所有异常?
最佳答案
当您在类
的定义期间从基类继承时,继承的默认访问修饰符是private
。这意味着以下两个定义是等价的:
class derived : base { /* ... */ };
class derived : private base { /* ... */ };
该语言不允许1您引用来自私有(private)基类的派生类2。例如,以下代码无法编译:
int main()
{
derived d;
base& b = d; // <== compilation error
}
error: 'base' is an inaccessible base of 'derived' base& b = d; ^
这就是为什么您的 catch
block 无法处理 Exception
的原因。将您的继承更改为 public
...
class Exception : public std::exception
...您的原始代码将起作用。
1 参见 [dcl.init.ref]和 [conv.ptr] .
2 除非您在 derived
本身的范围内。看这个live example on wandbox.org .
关于c++ - 无法通过引用 std::exception 捕获从 std::exception 派生的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50133365/