【问题标题】:Catch all Class Exceptions捕获所有类异常
【发布时间】:2019-01-18 18:27:25
【问题描述】:

我试图让用户选择从我的班级中捕获所有错误或单独捕获它们。我可以捕获单个异常,但是当我尝试捕获基本错误类时无法正确捕获它。我从 std::exception “未知错误”中得到标准错误。

我试图捕获基本异常并捕获派生错误。

我可以将我的所有错误都作为基本错误类型并全部捕获吗?

#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;
    }

有没有办法做到这一点,或者模板有可能吗?

【问题讨论】:

  • 没有一个派生类初始化它们的FooException 子对象。为什么是多重继承?
  • 当涉及到异常时,确实没有理由使用多重继承。
  • 你喜欢在自己的脚上开枪吗?
  • 您正在强制使用diamond problem。您的异常从std::exception 继承了两次。
  • 我的意思是他们只是默认初始化它们,当然。

标签: c++ class exception


【解决方案1】:

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

您在这里遇到的实际问题是代码显式初始化了其中一个基,但默认初始化了另一个; catch 子句获取FooException 对象,该对象具有默认初始化的std::exception,这就是您得到的消息。

正如一些 cmets 所暗示的,这是一个复杂的类层次结构,您无法解决这个问题。为避免拥有std::exception 的多个副本,您需要在使用它的两个地方从std::exception 继承虚拟FooException 中的继承很容易更改,但您无法更改 std::runtime_exception 并非虚拟派生自 std::exception 的事实。

因此存在设计问题,您必须准确决定要向用户提供什么。此层次结构比您在问题中描述的要多,因为它提供了 both FooException 部分标准异常层次结构。选择一个:要么使用标准异常层次结构,要么使用您自己的异常层次结构,FooException 派生自 std::exception 并提供初始化 std::exception 子对象的构造函数。

【讨论】:

  • 另外,有一个 hack 可以使这个工作,但我不想把它放在答案中,因为这意味着这是一个好主意。更改FooException,使其不派生自std::exception,并将其析构函数(或任何其他成员函数)设为虚拟。然后你可以捕获const FooException&amp; ex 并使用dynamic_cast&lt;const std::exception&amp;&gt;(ex) 到达std::exception 子对象。
  • 您有推荐的网站或书籍吗?我想更多地了解我自己的异常层次结构的优势。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-11-01
  • 2011-11-09
  • 1970-01-01
  • 2022-11-23
  • 2011-08-20
  • 1970-01-01
  • 2014-05-01
相关资源
最近更新 更多