Sobes.tech
Junior
121
questionbank

Какие умные указатели (smart pointers) вы знаете?

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

sobes.tech AI

std::unique_ptr, std::shared_ptr, std::weak_ptr, std::auto_ptr (устарел в C++11 и удален в C++17).

  • std::unique_ptr: Эксклюзивное владение ресурсом. Ресурс освобождается, когда указатель выходит из области видимости или сбрасывается. Не допускает копирования, только перемещение.

    #include <memory>
    
    int main() {
        std::unique_ptr<int> ptr(new int(5));
        // std::unique_ptr<int> ptr2 = ptr; // Ошибка: не копируется
        std::unique_ptr<int> ptr3 = std::move(ptr); // Перемещение
        return 0;
    }
    
  • std::shared_ptr: Совместное владение ресурсом. Использует счетчик ссылок. Ресурс освобождается, когда последний shared_ptr, указывающий на него, выходит из области видимости или сбрасывается. Поддерживает копирование.

    #include <memory>
    
    int main() {
        std::shared_ptr<int> ptr1(new int(10));
        std::shared_ptr<int> ptr2 = ptr1; // Копирование, счетчик ссылок увеличивается
        return 0;
    }
    
  • std::weak_ptr: Не владеет ресурсом и не увеличивает счетчик ссылок shared_ptr. Используется для предотвращения циклических ссылок между shared_ptr. Для доступа к ресурсу необходимо получить shared_ptr с помощью метода lock().

    #include <memory>
    
    int main() {
        std::shared_ptr<int> shared_ptr_inst(new int(20));
        std::weak_ptr<int> weak_ptr_inst = shared_ptr_inst; // Создание weak_ptr
    
        if (auto locked_ptr = weak_ptr_inst.lock()) {
            // Успешно получен shared_ptr, можно использовать ресурс
        } else {
            // Ресурс уже освобожден
        }
        return 0;
    }
    
  • std::auto_ptr: Устаревший умный указатель с семантикой владения при копировании, что приводило к неочевидному поведению. Не следует использовать в новом коде.

Различия между shared_ptr и weak_ptr:

Признак std::shared_ptr std::weak_ptr
Владение ресурсом Да Нет
Счетчик ссылок Увеличивает Не увеличивает
Освобождение ресурса Да, когда счетчик = 0 Нет
Циклические ссылки Может вызывать Помогает предотвратить
Доступ к ресурсу Напрямую operator*, operator-> Через метод lock()