С++ 11: Замените все необработанные указатели на std:: shared_ptr()?
С появлением std::unique_ptr
поврежденный std::auto_ptr
можно окончательно отложить. Поэтому в течение последних нескольких дней я меняю свой код на использование интеллектуальных указателей и устраняю все delete
из своего кода.
Хотя valgrind говорит, что мой код чист в памяти, семантическое богатство интеллектуальных указателей сделает более чистый и понятный код.
В большинстве кода перевод прост: используйте std::unique_ptr
вместо необработанных указателей, удерживаемых собственными объектами, выкиньте delete
и тщательно побрызгайте get()
, reset()
и move()
вызовы, если необходимо, хорошо взаимодействовать с остальной частью кода.
Я нахожусь в точке, где теперь я переводя не владеющие исходными указателями на интеллектуальные указатели.
Поскольку я был осторожен с временами жизни моих объектов (я гарантирую, что мои модули зависят только в одном направлении), valgrind говорит мне, что у меня нет никаких неинициализированных чтений, оборванных указателей или утечек. Итак, технически, я мог бы просто оставить те не владеющие исходными указателями сейчас.
Однако один из вариантов заключается в том, чтобы изменить те не владеющие исходными указателями на std::shared_ptr
, потому что я знаю, что они ацикличны. Или, было бы лучше оставить их в качестве исходных указателей?
Мне нужны советы ветеранских пользователей умных указателей относительно того, какие правила вы используете, чтобы решить, следует ли сохранять не владеющие исходными указателями как есть, или перевести их в std::shared_ptr
, имея в виду, что я постоянно тестирую блок и проверяю свой код.
EDIT: Возможно, я ошибаюсь в использовании std::shared_ptr
- их можно использовать в сочетании с std::unique_ptr
, или это так, если я использую std::shared_ptr
, все дескрипторы также должны быть std::shared_ptr
?
Ответы
Ответ 1
Лично я так и делаю (более или менее):
- unique_ptrs предназначены для единоличного владения
- raw указатели означают, что тот, кто дал мне необработанный указатель, гарантирует, что срок жизни этого объекта будет соответствовать или превысит мою жизнь.
- shared_ptrs предназначены для совместного использования.
- weak_ptrs - это когда система хочет проверить, существует ли объект до его использования. Это редко встречается в моем коде, так как я нахожу его более чистым, чтобы система гарантировала срок службы всего, что он передал подсистему (в этом случае я использую необработанный указатель)
До сих пор я использую больше unique_ptrs, чем shared_ptrs, и более сырые указатели, чем слабые указатели.
Ответ 2
Используйте shared_ptr
, когда вам нужно, чтобы у нескольких вещей был свой ресурс (и те, кто владеет вещами, могут входить и выходить из области действия "случайно" ), используйте unique_ptr
, когда одна вещь владеет ресурсом и использует raw pointer, когда вам просто нужно обратиться к нему и не иметь его (и ожидать, что этот реферал не будет длиться дольше, чем существует ресурс).
Существует четвертый тип, тип raw-pointer-for- shared_ptr
, называемый weak_ptr
. Вы используете это, чтобы ссылаться на shared_ptr
, фактически не владея им; вы можете проверить, все ли объект там, и использовать его.
Ответ 3
Единственный не-владеющий смарт-указатель в стандартной библиотеке - std::weak_ptr
. Однако, чтобы использовать его, фактический объект-владелец должен удерживать pointee в std::shared_ptr
.
Я предполагаю, что вы использовали std::unique_ptr
для тех, что были раньше. Если теперь вы конвертируете их в shared_ptr
, у вас будет преимущество, которое ваши указатели, не относящиеся к владельцам, могут знать, что потерявший указатель владельца является ссылкой, в то время как необработанные указатели могут быть оставлены болтающимися, без каких-либо шансов, чтобы не принадлежащий ему компонент обнаружил это, Тем не менее, shared_ptr
будет нести (очень?) Небольшую производительность и накладные расходы памяти над unique_ptr
.
Лично я рекомендую использовать один shared_ptr
и много weak_ptr
вместо одного unique_ptr
и много raw-указателей в общем случае и использовать unique_ptr
, если у вас действительно есть проблемы с производительностью!