Каково различие между теми тремя, и как я закончу программу в случае исключения, которое я не могу обработать правильно?
Я бы посоветовал не использовать ни один из них . Вместо этого перехватите исключения, которые вы не можете обработать в main (), и просто вернитесь оттуда. Это означает, что вам гарантировано, что раскрутка стека происходит правильно и вызываются все деструкторы. Другими словами:
int main() {
try {
// your stuff
}
catch( ... ) {
return 1; // or whatever
}
}
terminate() автоматически вызывается когда возникает исключение, которое невозможно не может быть обработано. По умолчанию terminate() вызывает abort(). Вы можете установить пользовательский с помощью функции set_terminate().
abort() посылает сигнал SIGABRT.
exit() не обязательно является плохим решением. не обязательно плохо. Она успешно завершает приложение и вызывает функцию atexit() функции в порядке LIFO. Я не обычно не вижу такого в приложениях на C++ приложениях, однако, я вижу это во многих приложениях на базе unix, где посылает код выхода в конце. Обычно exit(0) означает успешный запуск приложения.
abort указывает на "ненормальный" конец программы и вызывает сигнал POSIX SIGABRT, что означает, что любой обработчик, который вы зарегистрировали для этого signal будет вызван, хотя программа все равно завершит послесловие в любом случае. Обычно вы используете abort
в программе на C, чтобы выйти из непредвиденного случая ошибки, когда ошибка, скорее всего, является ошибкой в программе, а не чем-то вроде неправильного ввода или сбоя сети. Например, вы можете прервать
, если будет обнаружено, что в структуре данных есть указатель NULL, хотя по логике этого никогда не должно происходить.
exit указывает на «нормальный» конец программы, хотя это все еще может указывать на сбой (но не на ошибку). Другими словами, вы можете выйти из
с кодом ошибки, если пользователь ввел ввод, который не может быть проанализирован, или файл не может быть прочитан. Код выхода 0 указывает на успех. exit
также необязательно вызывает обработчики перед завершением программы. Они регистрируются функциями atexit
и on_exit
.
std :: terminate - это то, что автоматически вызывается в программе C ++ при возникновении необработанного исключения. По сути, это эквивалент C ++ abort
, предполагающий, что вы сообщаете обо всех своих исключительных ошибках посредством выдачи исключений. Это вызывает обработчик, установленный функцией std :: set_terminate
, которая по умолчанию просто вызывает abort
.
В C ++ обычно нужно избегать вызова abort
или exit
в случае ошибки, поскольку лучше генерировать исключение и позволять коду дальше по стеку вызовов решать, нужно ли или уместно не завершать программу. Независимо от того, используете ли вы exit
для успеха, это вопрос обстоятельств - имеет ли смысл завершить программу где-нибудь, кроме оператора return в main
.
std :: terminate
следует рассматривать как последний инструмент сообщения об ошибках, даже в C ++.Проблема с std :: terminate
заключается в том, что обработчик terminate не имеет доступ к исключению, которое осталось необработанным, поэтому нет способа определить, что это было. Обычно гораздо лучше обернуть весь main блоком try {} catch (std :: exception & ex) {}
. По крайней мере, тогда вы можете сообщить больше информации об исключениях, происходящих из std :: exception
(хотя, конечно, исключения, которые не происходят из std :: exception
, все равно останутся необработанными).
Заключение тела main
в try {} catch (...) {}
не намного лучше, чем установка обработчика завершения, потому что снова у вас нет доступа к рассматриваемое исключение. Изменить: Ответ Нила Баттерворта, есть преимущество в том, что в этом случае стек раскручивается, что (несколько удивительно) неверно для необработанного исключения.