Подтвердить что ты не робот

С++ 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?

4b9b3361

Ответ 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, если у вас действительно есть проблемы с производительностью!