Error handling
E.31
Правильно упорядочивайте `catch`-блоки
Причина
catch-блоки вычисляются в том порядке, в котором они появляются, и один блок может скрыть другой.
Пример (плохой)
void f()
{
// ...
try {
// ...
}
catch (Base& b) { /* ... */ }
catch (Derived& d) { /* ... */ }
catch (...) { /* ... */ }
catch (std::exception& e) { /* ... */ }
}
Если Derived является производным от Base, обработчик Derived никогда не будет вызван. Блок «перехватить всё» гарантирует, что обработчик std::exception тоже никогда не будет вызван.
Контроль
Помечать все «скрывающие обработчики».
Con: Константы и неизменяемость
На константе не может возникнуть состояние гонки. Программу легче анализировать, когда многие объекты не могут изменять своё значение. Интерфейсы, гарантирующие «отсутствие изменений» передаваемых аргументов, значительно повышают читаемость.
Краткое описание правил констант:
- Con.1: По умолчанию делайте объекты неизменяемыми
- Con.2: По умолчанию делайте функции-члены
const - Con.3: По умолчанию передавайте указатели и ссылки на
const - Con.4: Используйте
constдля объектов, значения которых не изменяются после конструирования - Con.5: Используйте
constexprдля значений, вычисляемых во время компиляции