Обратите внимание, что этот вопрос связан с генерацией исключения из конструктора класса исключения , а не из какого-либо старого конструктора.Мне не удалось найти повторяющийся вопрос по stackoverflow.
В этой статье не рекомендуется выдавать такое исключение, но я с подозрением отношусь к приведенной технической причине (и автор, похоже, отказывается отпричина в комментариях).
Я приведу пример, а затем расскажу о своей интерпретации происходящего, что подразумевает, что в принципе не должно быть проблем с этим, по крайней мере, с технической точки зрения,Мой главный вопрос - правильна ли моя интерпретация или я что-то упускаю концептуально.
Пример: Предположим, что я хочу разделить все возможные исключения на два типа: User_Error
и Coder_Error
.Первый указывает, очевидно, что пользователь сделал что-то, что он не должен был делать, а второй указывает, что какая-то серьезная внутренняя проверка не удалась и что кто-то должен подать отчет об ошибке.Вот (явно упрощенный) набросок:
#include <stdexcept>
#include <string>
...
class Coder_Error : public std::runtime_error
{
public:
Coder_Error( const std::string& msg ) :
std::runtime_error( msg + " Please freak out and file a bug report!" )
{}
};
class User_Error : public std::runtime_error
{
protected:
static void check_state() const
{
... // May rely on static members of this class or other classes.
if ( validation_failed ) {
throw Coder_Error( "A useful description of the problem." );
}
}
public:
User_Error( const std::string& msg ) : std::runtime_error( msg )
{
check_state();
}
};
Теперь предположим, что я делаю throw User_Error( "Some useful message." );
в случае, если User_Error::check_state()
бросит.Что произойдет?
Интерпретация: Я ожидаю, что объект Coder_Error
будет брошен до того, как линия throw
in throw User_Error( "Some useful message." )
когда-либо встретится, и поэтому мы ненужно беспокоиться о двух исключениях, возникающих одновременно, или о чем-то подобном.Чтобы быть более точным, я ожидаю, что соответствующие шаги будут происходить в следующем порядке:
User_Error::User_Error
будет вызван.
User_Error::check_state
будет вызван.
Coder_Error::Coder_Error
будет вызван.
Объект Coder_Error
, созданный на шаге 3, будет брошен.
Начнется разматывание стека, и обычное выполнение будет остановлено, поэтому выполнение никогда не достигнет точки, в которой оно может throw
User_Error
, созданное на шаге 1. (IЯ предполагаю, что ошибки не обнаруживаются.)
Это правильно?