c++ - 无法通过引用 std::exception 捕获从 std::exception 派生的类

标签 c++ exception polymorphism

我创建了一个派生自 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;
               ^

live example on wandbox.org


这就是为什么您的 catch block 无法处理 Exception 的原因。将您的继承更改为 public...

class Exception : public std::exception

...您的原始代码将起作用。

live example on wandbox.org


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/

相关文章:

java - 使用 try/catch 将数字存储到用户定义的数组中,并在最后一个数组索引中继续

c++ - 请告诉我为什么虚函数在以下代码中不起作用

C++ 多态性,不完全向下转型

c++ - 为什么不总是应用 RVO/NRVO?

c++ - 计算几个链接矩形周围的边界

ruby-on-rails - 如何处理 gem 的异常

Java 编译器错误 : Missing Return Statement

c++ - C++ 中的非虚拟多态性

c++ - Eigen C++ 中的矩阵矩阵

c++ - C++ 中的多态性和虚函数