Основное отличие в управлении временем жизни объекта.
shared_ptr управляет ресурсом с помощью счетчика сильных ссылок. Объект уничтожается, когда последний shared_ptr, указывающий на него, прекращает свое существование (счетчик сильных ссылок становится равен нулю). shared_ptr увеличивает этот счетчик при копировании.
weak_ptr не претендует на владение объектом. Он хранит "слабую" ссылку на ресурс, управляемый shared_ptr, и не увеличивает счетчик сильных ссылок. weak_ptr не предотвращает уничтожение объекта. Его основная цель — получить доступ к объекту, если он еще существует, не участвуя в управлении его временем жизни.
Для доступа к объекту, на который указывает weak_ptr, необходимо преобразовать его в shared_ptr с помощью метода lock(). Этот метод возвращает shared_ptr, если объект еще жив, или пустой shared_ptr в противном случае.
Примеры использования:
shared_ptr может создавать циклические ссылки, которые приводят к утечкам памяти. weak_ptr используется для разрыва таких циклов.weak_ptr на отслеживаемый объект, чтобы не продлевать его время жизни искусственно.weak_ptr на объекты, чтобы они могли быть выгружены gc (если применимо, или просто уничтожены, если на них нет других сильных ссылок).Сводная таблица:
| Feature | shared_ptr | weak_ptr |
|---|---|---|
| Управление ресурсом | Да (сильная ссылка) | Нет (слабая ссылка) |
| Счетчик сильных ссылок | Увеличивает | Не увеличивает |
| Предотвращение уничтожения | Да | Нет |
| Прямой доступ к объекту | Да (->, *) | Нет (только через lock()) |
| Использование в циклических ссылках | Приводит к утечкам | Используется для их разрыва |
Пример с циклическими ссылками:
c