Какой умный указатель выбрать
Вопрос
Расскажите, чем отличаются unique_ptr, shared_ptr и weak_ptr, как они устроены и как вы выбираете между ними.
Попробуйте сами
Ответьте вслух за 2 минуты, как на собесе. Потом сверьтесь с тезисами: что прозвучало, а что нет.
Показать ответ и разбор
Коротко
Что должно прозвучать в ответе
unique_ptr: единоличное владение, только перемещение, размер сырого указателя
shared_ptr: совместное владение, управляющий блок со счётчиками, атомарные инкременты
weak_ptr: не владеет, lock() для доступа, разрыв циклов, кеши
make_unique и make_shared вместо new
По умолчанию unique_ptr, shared_ptr только при реально общем владении
Невладеющий доступ: сырой указатель или ссылка
Что могут спросить следом
- Чем опасен shared_ptr, созданный из this?
- Когда память объекта не вернётся сразу после смерти последнего shared_ptr?
- Как передавать shared_ptr в функцию?
Разбор
unique_ptr выражает единоличное владение: копировать нельзя, можно перемещать, с удалителем по умолчанию он не больше сырого указателя и ничего не стоит. Это выбор по умолчанию: фабрики возвращают unique_ptr, члены класса, владеющие ресурсом, тоже unique_ptr. shared_ptr для случаев, когда у объекта действительно несколько владельцев и непонятно, кто умрёт последним. Он хранит указатель на объект и на управляющий блок со счётчиками сильных и слабых ссылок и удалителем, счётчики меняются атомарно, поэтому копирование не бесплатное. Создаю через make_shared: одна аллокация на объект и блок. weak_ptr наблюдает без владения, доступ через lock(), нужен для разрыва циклов, например обратная ссылка от ребёнка к родителю, и для кешей. Если функции нужен только доступ, передаю T& или T*, а не умный указатель, а если она забирает владение, unique_ptr по значению.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.