Во-первых, давайте очень четко объясним, что делает спецификация исключения: это более или менее похоже на assert
, который нельзя отключить, утверждая, что вы не выйдете из функции с исключением прочее , чемте, которые отсутствуют.Таким образом, его полезность гораздо более ограничена, чем может показаться на первый взгляд;по большей части (и в этом случае я не могу представить себе исключение) единственной действительно полезной гарантией является throw()
, которая гарантирует, что исключение не будет выдано;если вы хотите написать безопасный код исключения, вам понадобится эта гарантия для нескольких низкоуровневых функций.
На практике, хотя throw()
может позволить некоторые дополнительные оптимизации компилятора, общая реализация имеет тенденцию приводить к меньшемуэффективный код, когда используется спецификация исключения.В C ++ 11 throw()
был заменен на noexcept
, вероятно, с надеждой, что разработчики компилятора сделают с ним что-то умное.
РЕДАКТИРОВАТЬ:
Поскольку все (включаяя), кажется, пропустил ваш вопрос 4:
bad_alloc
будет выброшен функцией operator new
, если она не может выделить память.
bad_cast
будет выброшен dynamic_cast
на ссылку, в случае неудачного приведения.(A dynamic_cast
для указателя возвращает нулевой указатель в таких случаях.)
bad_exception
будет выброшено при нарушении спецификации исключения, при условии, что спецификация исключения допускает bad_exception
.(Другими словами, забудьте об этом.)
bad_typeid
будет брошено, если вы попытаетесь использовать typeid
с нулевым указателем.
ios_base::failure
будет брошено, если вы запроситепоток, который нужно выдать в случае ошибок.
Практически: вы поймаете bad_alloc
, если захотите восстановить и продолжить из нехватки памяти.Что значит не очень часто.(Это очень, очень трудно восстановить из ситуации нехватки памяти.) Для bad_cast
, вероятно, предпочтительнее использовать указатели и проверять на ноль, если вы не уверены.И нет никакого оправдания для того, чтобы когда-либо видеть bad_typeid
.В большинстве случаев вы, вероятно, захотите явно тестировать ошибки ввода-вывода, а не настраивать поток для выдачи исключений;и исключение, когда установлено ios_base::badbit
, может быть исключением (поскольку оно представляет собой действительно исключительный случай жесткого сбоя).