Move-only объекты и почему std::unique_ptr нельзя копировать
Многие удивляются, когда компилятор ругается: «unique_ptr не имеет конструктора копирования». Это не баг, а фича: он move-only. Логика простая: владелец ресурса должен быть только один.
#include <memory>
#include <iostream>
int main() {
std::unique_ptr<int> p1 = std::make_unique<int>(42);
// std::unique_ptr<int> p2 = p1; // ❌ ошибка копирования
std::unique_ptr<int> p2 = std::move(p1); // ✅ перенос
std::cout << *p2 << "\n"; // 42
std::cout << (p1 ? "not null" : "null") << "\n"; // null
}
Ключевой момент: после std::move старый указатель «обнуляется», чтобы избежать двойного освобождения памяти.
Если нужен shareable ресурс – используйте std::shared_ptr. Но помните: это дороже (счётчик ссылок, атомики).
Частая ошибка на собеседованиях: «почему нельзя вернуть unique_ptr по значению?» - на самом деле можно! Он спокойно двигается:
std::unique_ptr<int> make_ptr() {
return std::make_unique<int>(99); // move происходит неявно
}
👉 Правило: если объект владеет чем-то уникально – делайте его move-only (удалите копирование). Это повышает безопасность кода и явно выражает семантику владения.
➡️
@channel_cpp_geek