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

Joa*_*ald 4 c++ polymorphism exception

我创建了一个派生自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;
    }
}   
Run Code Online (Sandbox Code Playgroud)

这个程序在Ubuntu上由g ++ -stdc ++ = 17编译时,导致异常不会被catch块捕获,即使按引用捕获也应该捕获派生的异常.它调用std :: terminate,即使它发生在try块中,它通过引用捕获它的基类.如果Exception继承自std :: runtime_error并将"test"传递给自己的构造函数中的std :: runtime_error构造函数,则会发生同样的事情.通常解决方案只是使用Exception捕获,但在我的原始代码中,我需要捕获不同类型的异常,所有异常都继承自std :: exception.为什么会这样?参考基地的捕捉不起作用吗?如何使用一个catch块捕获从std :: exception派生的所有异常?

Vit*_*meo 5

在定义a期间从基类继承时,继承class的默认访问修饰符为private.这意味着以下两个定义是等效的:

class derived : base { /* ... */ };
class derived : private base { /* ... */ };
Run Code Online (Sandbox Code Playgroud)

语言不允许1您从私有基指派生类2.例如,以下代码无法编译:

int main()
{
    derived d;
    base& b = d; // <== compilation error
}
Run Code Online (Sandbox Code Playgroud)
error: 'base' is an inaccessible base of 'derived'
     base& b = d;
               ^
Run Code Online (Sandbox Code Playgroud)

wandbox.org上的实例


这就是你的catch块无法处理的原因Exception.将你的继承改为public......

class Exception : public std::exception
Run Code Online (Sandbox Code Playgroud)

...并且您的原始代码将起作用.

wandbox.org上的实例


1[dcl.init.ref][conv.ptr].

2除非你在derived自己的范围内.在wandbox.org上查看此实例.