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

Обновить

November 2018

Просмотры

2.7k раз

14

Сегодня я нашел ошибку в catchблоке:

catch (const exception& e){
    // do something
    // throw e; <-- bug!
    throw;    // <-- right thing to do
}

В принципе , если я повторно выдать исключение e явно , я получаю новое std::exceptionреконструированное, в действительности сообщения от what()метода было по умолчанию std::string, вместо того , чтобы мои пользовательские встроенное сообщение.

Что такое объяснение? Я думал , что throw;это только сокращенная из throw ExceptionJustCaught;.

2 ответы

14

Объекты исключений немного особенные. Они построены в специальном месте в памяти, и их жизнь определяются улов блок, в котором они поймали.

Если вы говорите throw e;, время жизни оригинального исключения заканчивается в конце блока поймать, и вы бросаете новое исключение путем копирования e, создав тем самым классический нарезки проблемы: Так как eэто полиморфная ссылка на объект, динамический тип, как правило , более -derived чем std::exception, вы в конечном итоге отрезая производную часть объекта.

Напротив, throw;это специальное заявление , которое не задействуется оригинальное исключение, так что это уже не поймают, и ее жизни ничего не заканчивается в конце блока больше. В самом деле, если вы ловите с непостоянной ссылкой, вы можете сохранить изменения объекта исключения и Rethrow и таким образом связываются состояние изменится до нижних блоков улова. Но имейте в виду , что rethrowning отличается от метания новое исключение!

8

Просто throwкидает текущее исключение по ссылке. throw eкопия создает новое исключение для броска. Это так же способ returnработает.

Связанные вопросы