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

Какие существуют умные указатели, кроме auto_ptr и unique_ptr?

Sobes Copilot

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

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

sobes.tech AI

  • shared_ptr: Указатель, которому могут принадлежать несколько объектов shared_ptr. Объект, на который он указывает, будет уничтожен, когда связанный с ним shared_ptr перестанет существовать (например, выйдет из области видимости) и ни один другой shared_ptr больше не будет на него указывать. Использует счетчик ссылок.

  • weak_ptr: Указатель, который ссылается на объект, которым владеет shared_ptr, но не увеличивает счетчик ссылок. Он не управляет временем жизни объекта. Используется для предотвращения циклических ссылок между shared_ptr. Для доступа к объекту необходимо сначала преобразовать weak_ptr в shared_ptr с помощью метода lock().

  • intrusive_ptr (не входит в стандартную библиотеку, но распространен): Указатель, который предполагает, что сам объект, на который он указывает, содержит счетчик ссылок. Управление временем жизни осуществляется за счет инкрементации и декрементации этого встроенного счетчика. Требует от пользователя реализации методов инкрементации и декрементации счетчика ссылок в самом классе объекта.

Пример использования shared_ptr и weak_ptr:

#include <iostream>
#include <memory>

class MyClass {
public:
    ~MyClass() {
        std::cout << "MyClass destroyed" << std::endl;
    }
};

int main() {
    std::shared_ptr<MyClass> shared1 = std::make_shared<MyClass>();
    std::shared_ptr<MyClass> shared2 = shared1; // shared_ptr копируется, счетчик ссылок увеличивается

    std::weak_ptr<MyClass> weak1 = shared1; // weak_ptr не увеличивает счетчик ссылок

    if (std::shared_ptr<MyClass> temp = weak1.lock()) {
        // Объект еще существует, можно работать с temp
        std::cout << "Object is still alive via weak_ptr" << std::endl;
    }

    shared1.reset(); // Счетчик ссылок уменьшается
    shared2.reset(); // Счетчик ссылок становится 0, объект уничтожается

    if (std::shared_ptr<MyClass> temp = weak1.lock()) {
        // Этот блок не выполнится, так как объект уничтожен
    } else {
        std::cout << "Object is no longer alive via weak_ptr" << std::endl;
    }

    return 0;
}

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

Характеристика shared_ptr weak_ptr
Управление жизнью Да (увеличивает счетчик ссылок) Нет (не влияет на счетчик)
Доступ к объекту Прямой доступ (->, *) Требует преобразования в shared_ptr (lock())
Предотвращение циклов Нет Да