Назад к вопросам
Middle
318
questionbank
Как работает shared_ptr в C++?
Sobes Copilot
Получайте ответы в реальном времени
Ответ от нейросети
sobes.tech AI
shared_ptr — это умный указатель, реализующий семантику владения разделяемым ресурсом. Он хранит указатель на объект и указатель на управляющий блок.
Управляющий блок содержит:
- Счетчик сильных ссылок (reference count).
- Счетчик слабых ссылок (weak count).
- Пользовательский функтор удаления (deleter), если задан.
- Пользовательский аллокатор, если задан.
- Указатель на хранимый объект (то же самое, что хранится в самом
shared_ptr).
Принцип работы:
- Создание: При создании первого
shared_ptr, указывающего на объект, создается управляющий блок, счетчики ссылок инициализируются: сильных — 1, слабых — 0.std::shared_ptr<int> ptr1 = std::make_shared<int>(10); // Создает объект int и управляющий блок - Копирование: При копировании
shared_ptrсчетчик сильных ссылок в управляющем блоке увеличивается на 1.std::shared_ptr<int> ptr2 = ptr1; // Увеличивает счетчик сильных ссылок - Присваивание: При присваивании
shared_ptrстарому ресурсу Decrement-ится (уменьшается) счетчик сильных ссылок, а новому ресурсу Increment-ится (увеличивается).std::shared_ptr<int> ptr3; ptr3 = ptr1; // Decrement ptr3's старого ресурса, Increment ptr1's ресурса - Удаление: При уничтожении
shared_ptr(например, выход из области видимости) счетчик сильных ссылок Decrement-ится.{ std::shared_ptr<int> ptr4 = ptr1; // Увеличивает счетчик сильных ссылок // ptr4 выходит из области видимости } // Decrement-ит счетчик сильных ссылок - Освобождение ресурса: Когда счетчик сильных ссылок достигает нуля, ресурс (объект, на который указывает
shared_ptr) удаляется с использованием заданного функтора удаления (илиdeleteпо умолчанию). - Освобождение управляющего блока: Управляющий блок освобождается, когда оба счетчика (сильных и слабых) достигают нуля.
Преимущества:
- Автоматическое управление памятью для разделяемых ресурсов.
- Безопасность от двойного освобождения.
- Поддержка пользовательских функторов удаления.
Недостатки:
- Циклические ссылки могут привести к утечкам памяти (решается с помощью
weak_ptr). - Незначительное увеличение накладных расходов из-за управляющего блока и атомарных операций со счетчиками.
- Потокобезопасность операций со самим
shared_ptr(копирование, присваивание, изменение хранимого указателя), но не с объектом, на который он указывает.