Выбрасывайте по значению, ловите исключения из иерархии по ссылке
Причина
Выбрасывание по значению (не по указателю) и ловля по ссылке предотвращают копирование, особенно нарезание базовых подобъектов.
Пример; плохой
void f()
{
try {
// ...
throw new widget{}; // не делайте: выбрасывайте по значению, не по сырому указателю
// ...
}
catch (base_class e) { // не делайте: может нарезаться
// ...
}
}
Вместо этого используйте ссылку:
catch (base_class& e) { /* ... */ }
или - типично лучше всё же - const ссылку:
catch (const base_class& e) { /* ... */ }
Большинство обработчиков не изменяют своё исключение и в целом мы рекомендуем использование const.
Примечание
Ловля по значению может быть уместна для малого значения типа, такого как значение enum.
Примечание
Для повторного выброса перехваченного исключения используйте throw; вместо throw e;. Использование throw e; выбросит новую копию e (нарезанную до статического типа std::exception, когда исключение ловится как catch (const std::exception& e)) вместо повторного выброса оригинального исключения типа std::runtime_error. (Но имейте в виду Не пытайтесь ловить каждое исключение в каждой функции и Минимизируйте использование явного try/catch.)
Применение
- Отмечайте ловлю по значению типа, у которого есть виртуальная функция.
- Отмечайте выброс сырых указателей.