Объекты · Классы и память

Перемещение

Почему C++ быстрый: забираем ресурс вместо копирования

~30 мин 6 шагов

После урока ты сможешь

  • Объяснять разницу между копированием и перемещением
  • Использовать std::move по делу и не использовать без него
  • Следовать правилу нуля

Шаг 1 из 6

Зачем копировать, если можно забрать

Функция собирает отчёт из миллиона строк и возвращает его. Строки не нужны там, где они были, они нужны там, куда их отдают. Копировать миллион строк, чтобы тут же уничтожить оригинал, глупо. Гораздо дешевле забрать их: переписать несколько указателей внутри вектора, а не копировать содержимое.

Это и есть перемещение — одна из главных причин, почему C++ быстрый. У std::string, std::vector и std::unique_ptr перемещение стоит почти ничего, независимо от размера данных.

main.cpp
#include <print>
#include <string>
#include <utility>
#include <vector>
​
int main() {
    std::string big(1'000'000, 'x');
​
    std::string copy = big;             // копирование: миллион символов
    std::string moved = std::move(big); // перемещение: забрали буфер
​
    std::println("copy: {}, moved: {}, big: {}", copy.size(), moved.size(), big.size());
}

После перемещения big скорее всего пуст. Стандарт гарантирует только, что объект остался в корректном, но неопределённом состоянии: его можно уничтожить или присвоить ему новое значение, но полагаться на его содержимое нельзя.

Проверь себя

После std::string b = std::move(a); что можно делать с a?