Назад к вопросам
Middle
169
questionbank

Как работает unique_ptr в C++?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

std::unique_ptr — это смарт-указатель, который реализует эксклюзивное владение динамически выделенным объектом. Он обеспечивает автоматическое управление памятью: объект, на который указывает unique_ptr, автоматически удаляется при уничтожении unique_ptr.

Ключевые особенности:

  • Эксклюзивное владение: В любой момент времени только один unique_ptr может владеть конкретным объектом.
  • Отсутствие копирования: unique_ptr не может быть скопирован. Это предотвращает множественное владение одним и тем же объектом и проблему "двойного удаления".
  • Семантика перемещения: Владение объектом может быть передано от одного unique_ptr к другому с использованием семантики перемещения (std::move).
  • Настраиваемый удалитель: Можно предоставить собственный удалитель (deleter) для управления специфическими способами освобождения ресурсов.

Принцип работы основан на RAII (Resource Acquisition Is Initialization): ресурс (динамически выделенная память) приобретается при создании объекта (unique_ptr), а освобождается при уничтожении этого объекта.

#include <memory> // Для unique_ptr
#include <iostream>

class MyClass {
public:
    MyClass() { std::cout << "MyClass created\n"; }
    ~MyClass() { std::cout << "MyClass destroyed\n"; }
};

int main() {
    {   
        // Создание unique_ptr, владеющего объектом MyClass
        std::unique_ptr<MyClass> ptr1 = std::make_unique<MyClass>(); 
        
        // В этот момент ptr1 является эксклюзивным владельцем объекта
        // auto ptr2 = ptr1; // Ошибка компиляции: копирование запрещено

        // Передача владения от ptr1 к ptr2
        std::unique_ptr<MyClass> ptr2 = std::move(ptr1); 
        
        // После перемещения ptr1 больше не владеет объектом (стал nullptr)
        if (!ptr1) {
            std::cout << "ptr1 владеет объектом: " << (ptr1 ? "Да" : "Нет") << "\n";
        }

        // Область видимости для ptr2 заканчивается.
        // ptr2 уничтожается, и объект MyClass, которым он владеет, автоматически удаляется.
    } // Объект MyClass уничтожается здесь

    std::cout << "Конец main.\n";

    return 0;
}

Сравнение с raw pointer:

Характеристика raw pointer std::unique_ptr
Владение ресурсом Не определено Эксклюзивное
Автоматическое удаление Нет Да
Семантика копирования Да Нет (только перемещение)
Утечки памяти Высокий риск Низкий риск

В целом, unique_ptr — это предпочтительный способ управления динамической памятью в C++11 и выше для случаев, когда требуется строгое владение и автоматическое освобождение ресурсов.