Катя мои собственные исключения - PullRequest
1 голос
/ 03 декабря 2008

Я пишу новый код, который будет выдавать пользовательское исключение - я хочу включить строку ошибки и код состояния. От какого класса должно быть исключение? std::exception? std::runtime_error? Есть ли еще какие-то проблемы, о которых стоит беспокоиться? Я думаю о чем-то вроде следующего:

class MyException : public std::exception(?)
{
public:
    enum Status
    {
        ERROR_FOO,
        ERROR_BAR,
        ...
    };

    MyException(const std::string& error, Status code) :
        error_(error), code_(code)
    {
        ...
    }

    virtual const char* what() const
    {
        return error_.c_str();
    }

    Status code() const
    {
        return code_;
    }
private:
    std::string error_;
    Status code_;
};

Тогда в коде:

throw MyException("Ooops!", MyException::ERROR_BAR);

Ответы [ 6 ]

8 голосов
/ 03 декабря 2008

Boost имеет отличный документ по обработке ошибок и исключений , в котором говорится об общих ошибках и о том, как правильно наследовать от std :: exception (s).

6 голосов
/ 03 декабря 2008

Подумайте, действительно ли код статуса подходит. Обычно лучше создать иерархию классов исключений. Таким образом, вызывающая сторона может лучше контролировать, какие исключения обрабатывать и как, и это упрощает интерфейс.

Конечно, иногда коды состояния все еще уместны (компиляторы используют их постоянно).

3 голосов
/ 03 декабря 2008

Вы можете использовать любой стандартный тип исключения в качестве основы, но он действительно поможет пользователям класса (включая вас), если вы выберете правильный тип:

  • Если ошибка является чем-то, чего можно было бы избежать, если бы пользователь был более осторожным или точным, используйте logic_error .
  • Если что-то исходит из системы, что пользователь не смог предотвратить, используйте runtime_error .

Конечно, вы также можете использовать одно из других стандартных производных исключений (например, invalid_argument, range_error, bad_cast), если оно лучше описывает ошибку.

2 голосов
/ 03 декабря 2008

Ваш класс исключений не является безопасным для исключений. Если копировать конструктор исключения std :: string, программа будет остановлена.

class MyException : public std::exception
{
public:
    enum Status
    {
        ERROR_FOO,
        ERROR_BAR,
        ...
    };

    MyException(const char* error, Status code) :
        std::exception(error),
        code_(code)
    {
        ...
    }
    ...
private:
    Status code_;
};
1 голос
/ 03 декабря 2008

Очень полезным ресурсом в этом отношении является C ++ FAQ LITE от Marshall Cline. У него есть глава по исключениям и обработке ошибок , которая может быть вам полезна.

0 голосов
/ 03 декабря 2008

Методы-деструктор и what () должны быть помечены как нет.
В MS-Studio он игнорирует спецификатор throw и прекрасно компилируется, но для соответствия стандарту и переносимости вы должны добавить его в свой код.

// What is a no throw operation.
virtual const char* what() const throw ()
{
    return error_.c_str();
}

Другие комментарии:

Я бы не наследовал напрямую от исключения.
Посмотрите на стандартные исключения, полученные из исключения, и посмотрите, соответствуют ли они требованиям.

Вместо использования кода ошибки. Вы можете использовать иерархию типов исключений. Это облегчает ловлю.

class MyException: public std::runtime_error
{  // STUFF  .. Put all the error message stuff here
};

class MyFOO_Exception: public MyException
{  // STUFF
};

class MyBAR_Exception: public MyException
{  // STUFF
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...