Гарантии безопасности исключений
Вопрос
Расскажите о гарантиях безопасности исключений и о том, как писать код, который их соблюдает. Приведите пример со строгой гарантией.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
Nothrow, строгая, базовая: определения
RAII как основа: деструкторы освобождают всё при раскрутке
Строгая гарантия через copy-and-swap или «сначала всё, что может бросить, потом коммит»
noexcept на move, swap, деструкторах; влияние на vector
Деструкторы не бросают
Примеры из стандартной библиотеки: push_back строгая, insert в середину базовая
Что могут спросить следом
- Почему vector::insert в середину даёт только базовую гарантию?
- Как noexcept влияет на выбор между копированием и перемещением?
Разбор
Гарантии описывают, в каком состоянии останется программа, если операция бросила. Nothrow: не бросает никогда, это деструкторы, swap, перемещения. Строгая: всё или ничего, состояние как до вызова. Базовая: объекты корректны и нет утечек, но значения могли измениться. Основа всего RAII: при раскрутке деструкторы сами освобождают ресурсы, поэтому без сырых new базовая гарантия получается почти бесплатно. Строгую я делаю по схеме «сначала всё, что может бросить, потом коммит из nothrow-операций». Например, присваивание через copy-and-swap: копия строится в параметре, а затем noexcept-обмен; или обновление нескольких полей: готовлю новые значения во временных переменных и только потом присваиваю их noexcept-перемещением. Перемещения и swap помечаю noexcept, иначе std::vector при росте будет копировать ради собственной строгой гарантии push_back. Деструкторы не бросают никогда. Вставка в середину вектора даёт только базовую гарантию, потому что элементы уже сдвинуты к моменту возможного исключения.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.