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?
答案 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
子对象的构造函数。