Catch all Class Exceptions

时间:2019-01-18 18:27:25

标签: c++ class exception

I am trying to give the user the option to catch all the errors from my class or to catch them individually. I can catch individual exceptions but I can't catch it correctly when I try to catch the base error class. I get the standard error from std::exception "Unknown Error".

I have tried to catch the base exception and to catch the derived errors.

Can I have all my errors be a base error type and catch them all as such?

#include <iostream>
#include <exception>

struct FooException 
    : public std::exception
{

};

struct FooRuntimeException
    : public std::runtime_error,
    public FooException
{
    FooRuntimeException(const char* what)
        : runtime_error(what) {}

};

struct FooRangeError
    : public std::range_error, 
    public FooException
{
    FooRangeError(const char* what)
        : range_error(what) {}
};


class Foo
{
public:
    Foo() = default;
    ~Foo() {};

    void throwRunTimeException()
    {
        throw FooRuntimeException("Runtime Error");
    }
    void throwRangeError()
    {
        throw FooRuntimeException("Range Error");
    }
};

int main()
{
    try
    {
        auto foo = Foo();
        foo.throwRunTimeException();
    }
    catch (const FooException &e)
    {
        std::cerr << e.what(); // catches standard error message
    }

    return 0;
    }

Is there a way to do this or is templates a possibility?

1 个答案:

答案 0 :(得分:4)

您会感到困惑,因为每个异常类中都有两个std::exception类型的基类。尝试捕获const std::exception&,并注意编译器的抱怨。

您在这里遇到的实际问题是,代码显式地初始化了其中一个基址,而default初始化了另一个基址。 catch子句获取FooException对象,该对象具有默认初始化的std::exception,因此您将收到消息。

正如一些评论所暗示的那样,这是一个复杂的类层次结构,您无法做很多事情来解决该问题。为了避免拥有std::exception的多个副本,您需要在使用的两个地方从std::exception继承 virtually FooException中的继承很容易更改,但是您不能更改std::runtime_exception实际上不是从std::exception派生的事实。

因此存在设计问题,您必须准确确定要提供给用户的内容。此层次结构的作用超出了您在问题中描述的范围,因为它提供了标准异常层次结构的两者 FooException 部分。选择一个:要么使用标准异常层次结构,要么使用自己的异常层次结构,其中FooException源自std::exception,并提供用于初始化std::exception子对象的构造函数。