Какие умные указатели есть в стандартной библиотеке C++?

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

Ответ

В C++ стандартная библиотека предоставляет несколько умных указателей в заголовке <memory>, которые автоматически управляют временем жизни динамически выделенных объектов, предотвращая утечки памяти.

Основные умные указатели:

  1. std::unique_ptr<T> — обеспечивает эксклюзивное (единоличное) владение объектом. Некопируем, но перемещаем.

    {
        std::unique_ptr<MyClass> ptr = std::make_unique<MyClass>(); // Выделение
        ptr->doWork(); // Использование
    } // Память автоматически освобождается здесь при выходе из области видимости
  2. std::shared_ptr<T> — реализует разделяемое владение через подсчёт ссылок. Объект уничтожается, когда удаляется последний shared_ptr, ссылающийся на него.

    auto ptr1 = std::make_shared<int>(42); // Счётчик = 1
    {
        std::shared_ptr<int> ptr2 = ptr1; // Счётчик увеличивается до 2
    } // ptr2 уничтожается, счётчик уменьшается до 1
    // ptr1 всё ещё владеет объектом
  3. std::weak_ptr<T> — «слабая» ссылка на объект, управляемый shared_ptr. Не увеличивает счётчик ссылок, используется для наблюдения и разрыва циклических зависимостей.

    std::weak_ptr<int> observer = ptr1;
    if (auto locked = observer.lock()) { // Попытка получить shared_ptr
        // Объект ещё жив, можно использовать через locked
    }

Ключевые моменты:

  • std::make_unique и std::make_shared предпочтительны для создания умных указателей, так как они безопаснее в отношении исключений.
  • std::auto_ptr устарел и удалён, начиная с C++17.
  • std::observer_ptr (C++20) — это невладеющий указатель, предназначенный в первую очередь для документирования семантики в интерфейсах.