Конструктор как функция try block - Exception aborts program
Я не уверен, что это проблема с компилятором, или если я делаю что-то неправильно. Я использую компилятор Visual Studio 2013.
У меня есть класс, в котором мне нужно получить значительное количество ресурсов в моем списке инициализаторов конструктора, большинство из которых могут генерировать исключение. Я завернул список инициализаторов членов в блоке try функции и поймал там исключение. Но моя программа все равно прерывается, хотя предложение catch не перебрасывает исключение. Мне не разрешено публиковать фактический код. Поэтому я воспроизвел проблему с этим эквивалентным демо-кодом. Может кто-то, пожалуйста, помогите мне в этом?
#include <iostream>
using namespace std;
class A{
public:
A() try : i{ 0 }{ throw 5; }
catch (...){ cout << "Exception" << endl; }
private:
int i;
};
int main(){
A obj;
}
При выполнении этого кода я получаю предупреждение о Windows: "abort() был вызван". Поэтому я предполагаю, что система рассматривает это как неперехваченное исключение и вызывает terminate().
С другой стороны, если я завершаю конструкцию объекта в main() в блоке try-catch, тогда исключение поймается правильно, и программа завершается нормально.
Может кто-нибудь, пожалуйста, скажите мне, что я здесь делаю что-то не так?
Ответы
Ответ 1
Там есть соответствующий getw
http://gotw.ca/gotw/066.htm
В принципе, даже если вы не вбрасываете свой блок catch, исключение автоматически будет перезапущено
Если тело обработчика содержало оператор "throw"; то уловка блок, очевидно, изменит любое исключение A:: A() или B:: B() излучается. Что менее очевидно, но четко указано в стандарте, что, если блок catch не бросает (либо реконструируйте оригинал исключение или выбросить что-то новое), и контроль достигнет конца блок catch конструктора или деструктора, затем оригинал исключение автоматически отменяется.
Ответ 2
Это нормальное поведение в соответствии с документацией cppreference.com для блоков try
: так называемая функция-try-block на конструкторе или деструкторе необходимо выкинуть из его catch-clause или же неявное ретронирование после catch-clause.
Это имеет смысл: объект A
не был правильно сконструирован и, следовательно, не находится в состоянии, пригодном для использования: он должен выдать исключение. Вы должны убедиться, что построение выполнено в том месте, где объект построен, т.е. В случае вашего примера в main()
.
Ответ 3
Исключение не может быть обнаружено в конструкторе function-try-block
.
n3376 15.2/15
Исключенное в настоящее время исключение возвращается, если контроль заканчивается обработчика функции-try-блока конструктора или деструктора.
Вы должны поймать его в месте создания объекта.
Ответ 4
Я предлагаю вам прочитать статью: "GotW # 66 Constructor Failures" на сайте: http://gotw.ca/gotw/066.htm