В чем разница между std::runtime_error
и std::exception
? Какое уместное использование для каждого? Почему они отличаются друг от друга?Разница: std :: runtime_error vs std :: exception()
ответ
std::exception
- класс, единственная цель которого - служить базовым классом в иерархии исключений. У него нет других применений. Другими словами, концептуально это класс (хотя он не определен как абстрактный класс в значении термина C++).
std::runtime_error
является более специализированным классом, спускаясь с std::exception
, предназначенным быть выброшено в случае различных времени выполнения ошибок. Он имеет двойную цель. Он может быть брошен сам по себе или может служить базовым классом для различных даже более специализированных типов исключений ошибок во время выполнения, таких как std::range_error
, std::overflow_error
и т. Д. Вы можете определить свои собственные классы исключений, спускающиеся с std::runtime_error
, а также вы можете определить ваши собственные классы исключений по убыванию от std::exception
.
Точно так же, как std::runtime_error
, стандартная библиотека содержит std::logic_error
, также по убыванию от std::exception
.
Суть этой иерархии - предоставить пользователю возможность использовать всю мощь механизма обработки исключений на языке C++. Поскольку предложение «catch» может ловить полиморфные исключения, пользователь может писать предложения «catch», которые могут захватывать типы исключений из определенного поддерева иерархии исключений. Например, catch (std::runtime_error& e)
будет перехватывать все исключения из поддерева std::runtime_error
, позволяя всем остальным проходить (и летать дальше по стеку вызовов).
P.S. Разработка полезной иерархии классов исключений (которая позволит вам улавливать только типы исключений, которые вас интересуют в каждой точке вашего кода) является нетривиальной задачей. То, что вы видите в стандартной библиотеке C++, - это один из возможных подходов, предложенный авторами этого языка. Как вы видите, они решили разделить все типы исключений на «ошибки времени выполнения» и «логические ошибки» и позволить вам перейти оттуда со своими собственными типами исключений. Конечно, есть альтернативные способы структурирования этой иерархии, которые могут быть более уместны в вашем дизайне.
Обновление: Переносимость Linux против Windows,
Как Loki Astari и unixman83 отметил в своем ответе и комментариях ниже, конструктор exception
класса не принимает никаких аргументов в соответствии со стандартом C++. Microsoft C++ имеет конструктор, принимающий аргументы в классе exception
, но это не стандарт. Класс runtime_error
имеет конструктор, принимающий аргументы (char*
) на обеих платформах, Windows и Linux. Чтобы быть портативным, лучше использовать runtime_error
.
(И помните, только потому, что спецификация вашего проекта говорит ваш код не должен работать на Linux, это не значит, что он не делает никогда не придется работать на Linux.)
станд :: исключение должно быть (обратите внимание на рассмотренную) абстрактную базу стандартной иерархии исключений. Это связано с тем, что в конкретном сообщении нет механизма для передачи (для этого вы должны получить и определить, что()). Нет ничего, что помешало бы вам использовать std :: exception, и для простых приложений это может быть все, что вам нужно.
С другой стороны, std :: runtime_error имеет действительные конструкторы, которые принимают строку как сообщение.Когда what() вызывается указателем const char, возвращается точка C, которая имеет ту же строку, что и в конструкторе.
try
{
if (badThingHappened)
{
throw std::runtime_error("Something Bad happened here");
}
}
catch(std::exception const& e)
{
std::cout << "Exception: " << e.what() << "\n";
}
Спасибо за ответ martin. Однако я использую std :: exception() так же, как описано выше. т. е. конструктор std :: exception() может также принимать std :: string() или const char *. – sivabudh
Не соответствует стандарту. std :: exception имеет один конструктор, который не принимает аргументов. Использование версии, принимающей std :: string или C-String, не переносится. –
Из-за Microsoft я привык бросать 'std :: exception (std :: string)'. Теперь я понимаю, что я должен бросить 'std :: runtime_error', если я хочу, чтобы мой код работал в Linux (GCC). – unixman83
- 1. Confused about std :: runtime_error vs. std :: logic_error
- 2. Ошибка с catching std :: runtime_error as std :: exception
- 3. Непонятно, что() функция std :: runtime_error
- 4. Не удалось поймать std :: runtime_error
- 5. std :: array vs std :: vector тонкая разница
- 6. Разница между std :: exception и "..."
- 7. Как наследовать от std :: runtime_error?
- 8. move constructor для std :: runtime_error
- 9. Новый резидентный агент iOS uncaught exception (std :: runtime_error)
- 10. Наследовать собственный класс исключений из boost :: exception и std :: runtime_error
- 11. Не удается поймать пользовательский std :: runtime_error
- 12. gcc 4.9.1 не соответствует стандарту? (std :: runtime_error)
- 13. std :: string constructor throws std :: out_of_range exception
- 14. Унаследовано от std :: exception, неопределенность в определениях std :: exception
- 15. std :: shared_ptr Exception Safety
- 16. std :: unique_ptr vs std :: shared_ptr vs std :: weak_ptr vs std :: auto_ptr vs raw указатели
- 17. C++ 0x random_device с 'std :: runtime_error'
- 18. Почему создается std :: runtime_error reset WSAGetLastError?
- 19. std :: this_thread :: yield() vs std :: this_thread :: sleep_for()?
- 20. Разница в использовании имен (Std :: против :: Std: :)
- 21. Относительная производительность std :: vector vs. std :: list vs. std :: slist?
- 22. std :: async vs std :: prom
- 23. std :: move Vs std :: forward
- 24. std :: условный vs std :: enable_if
- 25. std :: cin.getline() vs. std :: cin
- 26. std :: exceptions what() возвращает «std :: exception»
- 27. std future exception - уже получен, std ошибка?
- 28. Использование std :: forward vs std :: move
- 29. C++ std :: ostringstream vs std :: string :: append
- 30. , происходящий из std :: exception
спасибо. отличный ответ. хотя мне интересно, есть ли когда-либо необходимость иметь различный тип исключения ... просто мысль. – sivabudh
Если существует вероятность того, что исключение может быть повторно покрыто, тогда может быть полезен другой тип исключения, поскольку мы можем использовать механизм обработки исключений, чтобы направить исключение на обработчик, который попытается исправить проблему. Если нет шансов на восстановление, то одно из стандартных исключений - штраф. –
Так же, как и в стороне: нет никакого правила, нигде, что заставляет вас выводить из 'std :: exception'. Конечно, все 'std' вещи бросают производные классы этого, но нет абсолютно никаких оснований только бросать производные объекты std :: exception. – rubenvb