Ответ вслух Middle Move-семантика спрашивают часто обновлено

Объясни move-семантику

Вопрос

Объясните, зачем нужна move-семантика, как она работает и что такое std::move.

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

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

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

Коротко

Move-семантика нужна, чтобы не копировать данные, когда источник всё равно больше не понадобится: временный объект, результат функции, переменная, которую мы явно отдаём. Для вектора или строки перемещение это перенос пары указателей за O(1) вместо копирования всего буфера.

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

  • Перемещение забирает ресурсы у объекта, который больше не нужен: O(1) вместо копии

  • rvalue-ссылки и перегрузка: rvalue выбирает перемещающий конструктор

  • `std::move` только приведение к rvalue

  • Источник остаётся в корректном, но неуказанном состоянии

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

  • Copy elision и возврат по значению без std::move

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

  • Почему именованная rvalue-ссылка это lvalue?
  • Чем опасен std::move в шаблонах с T&&?
  • Что будет с перемещением, если в классе объявлен деструктор?

Разбор

Move-семантика нужна, чтобы не копировать данные, когда источник всё равно больше не понадобится: временный объект, результат функции, переменная, которую мы явно отдаём. Для вектора или строки перемещение это перенос пары указателей за O(1) вместо копирования всего буфера. Механизм простой: rvalue-ссылки T&& связываются только с rvalue, поэтому при перегрузке для временных объектов выбираются перемещающий конструктор и присваивание, которые забирают ресурс и оставляют источник в корректном, но неуказанном состоянии. std::move ничего не перемещает, это приведение к xvalue, которое разрешает выбрать перемещающую перегрузку; на const объекте оно приведёт к копированию. Перемещение стоит делать noexcept, иначе vector при росте будет копировать. И не нужно писать return std::move(local): возврат локальной переменной и так перемещает, а std::move мешает NRVO. С C++17 инициализация из prvalue вообще не создаёт промежуточных объектов.

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

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