Какие операции присваивания разрешены для std::unique_ptr?

«Какие операции присваивания разрешены для std::unique_ptr?» — вопрос из категории Управление памятью, который задают на 25% собеседований C/C++ Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

std::unique_ptr реализует семантику исключительного владения ресурсом. Поэтому разрешена только операция перемещающего присваивания. Копирующее присваивание и конструктор копирования явно удалены.

Разрешенные сценарии:

  1. Присваивание из временного объекта (rvalue) с помощью std::move:

    std::unique_ptr<int> ptr1 = std::make_unique<int>(42);
    std::unique_ptr<int> ptr2;
    ptr2 = std::move(ptr1); // OK: владение передается от ptr1 к ptr2
    // Теперь ptr1 == nullptr, ptr2 владеет int(42)
  2. Присваивание результата std::make_unique или другой фабричной функции:

    std::unique_ptr<MyClass> ptr;
    ptr = std::make_unique<MyClass>(); // OK: перемещение из временного объекта

Запрещенные сценарии:

std::unique_ptr<int> a = std::make_unique<int>(5);
std::unique_ptr<int> b = a; // Ошибка компиляции: конструктор копирования удален
b = a; // Ошибка компиляции: оператор копирующего присваивания удален

Это гарантирует, что в любой момент времени только один unique_ptr владеет конкретным динамическим объектом, что предотвращает двойное удаление и упрощает рассуждение о владении.