Ответ вслух Middle Правило 0/3/5 спрашивают часто обновлено

Правила 0, 3 и 5

Вопрос

Расскажите про правила нуля, трёх и пяти: откуда они взялись и как вы пишете классы на практике.

Попробуйте сами

Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.

Показать ответ и разбор

Коротко

Компилятор умеет генерировать конструктор по умолчанию, деструктор, копирование и перемещение, и делает это почленно. Это правильно, пока члены сами управляют своими ресурсами.

Что должно прозвучать в ответе

  • Шесть специальных функций, почленная генерация

  • Правило трёх: свой деструктор, значит свои копирования

  • Правило пяти: плюс перемещения, иначе перемещение станет копированием

  • Правило нуля: владение членам-RAII, ничего не объявлять

  • noexcept на перемещении ради vector

  • = delete для некопируемых типов

Что могут спросить следом

  • Что случится, если объявить только деструктор?
  • Когда класс должен быть только перемещаемым?

Разбор

Компилятор умеет генерировать конструктор по умолчанию, деструктор, копирование и перемещение, и делает это почленно. Это правильно, пока члены сами управляют своими ресурсами. Если же класс вручную владеет сырым ресурсом, ему нужен свой деструктор, а значит и своё копирование: правило трёх, иначе копия поделит указатель и будет двойное удаление. С C++11 добавились перемещающие операции, и правило стало правилом пяти: стоит объявить деструктор, как перемещение перестаёт генерироваться и молча превращается в копирование. На практике я стараюсь следовать правилу нуля: храню данные в std::vector, std::string, std::unique_ptr, и не пишу ни одной специальной функции. Если ресурс нестандартный, делаю одну маленькую RAII-обёртку с правилом пяти, перемещения помечаю noexcept, а бессмысленное копирование запрещаю через = delete, как у unique_ptr, мьютекса или потока.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.