Поймать все исключения класса - PullRequest
0 голосов
/ 18 января 2019

Я пытаюсь дать пользователю возможность отлавливать все ошибки из моего класса или отлавливать их по отдельности. Я могу перехватить отдельные исключения, но не могу правильно их отловить, когда пытаюсь поймать базовый класс ошибок. Я получаю стандартную ошибку из std :: исключение "Неизвестная ошибка".

Я пытался отловить базовое исключение и отловить полученные ошибки.

Могу ли я сделать так, чтобы все мои ошибки были базовым типом ошибки и перехватывали их как таковые?

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

Есть ли способ сделать это или шаблоны возможно?

1 Ответ

0 голосов
/ 18 января 2019

Вы запутались, потому что в каждом из ваших классов исключений есть два базовых класса типа std::exception.Попробуйте поймать const std::exception& и посмотрите, как компилятор жалуется.

Фактическая проблема, с которой вы здесь сталкиваетесь, заключается в том, что код явно инициализирует одну из этих баз, но по умолчанию инициализирует другую;предложение catch получает объект FooException, инициализированный по умолчанию std::exception, так что это сообщение, которое вы получаете.

Как подсказали некоторые комментарии, это сложная иерархия классов, и естьне так много вы можете сделать, чтобы решить проблему.Чтобы не иметь нескольких копий std::exception, вам нужно наследовать фактически от std::exception в двух местах, где он используется.Наследование в FooException легко изменить, но вы не можете изменить тот факт, что std::runtime_exception не является производным от std::exception.

Таким образом, существует проблема проектирования, и вы должны точно решить, чтоВы хотите предоставить пользователю.Эта иерархия делает больше, чем вы описываете в своем вопросе, поскольку она обеспечивает и FooException и части стандартной иерархии исключений.Выберите один: либо используйте стандартную иерархию исключений, либо используйте собственную иерархию исключений, при этом FooException происходит от std::exception и предоставляет конструктор, который инициализирует подобъект std::exception.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...