C ++ 11: Заменить все не владеющие необработанными указателями на std :: shared_ptr ()? - PullRequest
57 голосов
/ 01 декабря 2011

С появлением std::unique_ptr порочный std::auto_ptr наконец может быть остановлен. В течение последних нескольких дней я изменял свой код, чтобы использовать умные указатели и исключать все delete из моего кода.

Хотя Вальгринд говорит, что мой код очищает память, семантическое богатство умных указателей сделает код чище и проще для понимания.

В большей части кода перевод прост: используйте std::unique_ptr вместо необработанных указателей, удерживаемых объектами-владельцами, выбросьте delete и аккуратно посыпьте get(), reset() и move() при необходимости вызывается, чтобы хорошо взаимодействовать с остальным кодом.

Сейчас я перевожу не владеющие необработанными указателями на умные указатели.

Так как я был осторожен со временем жизни моих объектов (я гарантирую, что мои модули зависят только в одном направлении), valgrind говорит мне, что у меня нет никаких неинициализированных операций чтения, свисающих указателей или утечек. Так что технически я мог бы просто оставить эти не владеющих необработанными указателями в покое.

Однако, один из вариантов - поменять эти не владеющие необработанными указателями на std::shared_ptr, потому что я знаю, что они ациклические. Или лучше оставить их в качестве сырых указателей?

Мне нужно несколько советов от опытных пользователей умных указателей относительно того, какие эмпирические правила вы используете, чтобы решить, оставить ли не владеющие необработанными указателями как есть, или перевести их в std::shared_ptr, с учетом того, что я постоянно тестирую модуль и проверяю свой код.

РЕДАКТИРОВАТЬ: Я мог бы неправильно понимать использование std::shared_ptr - могут ли они использоваться вместе с std::unique_ptr, или это так, если я использую std::shared_ptr, все дескрипторы также должны быть std::shared_ptr?

Ответы [ 3 ]

104 голосов
/ 04 декабря 2011

Лично я так (более или менее) делаю это:

  • unique_ptrs для единоличного владения
  • необработанные указатели означают, что тот, кто дал мне необработанный указатель, гарантирует, что время жизни этого объекта соответствует или превышает мое время жизни.
  • shared_ptrs для совместного владения
  • weak_ptrs предназначены для случаев, когда система хочет проверить, существует ли объект до его использования. Это редко встречается в моем коде, так как я считаю чище иметь систему, гарантирующую время жизни всего, что она передает, своим подсистемам (в этом случае я использую необработанный указатель)

На данный момент я использую больше unique_ptrs, чем shared_ptrs, и больше необработанных указателей, чем слабых указателей.

11 голосов
/ 01 декабря 2011

Используйте shared_ptr, когда вам требуется, чтобы у ресурса было несколько вещей (а те, у кого есть вещи, могут входить и выходить из области действия «случайно»), использовать unique_ptr, когда ресурсу принадлежит одна вещь, и необработанный указатель, когда вам просто нужно сослаться на него, а не владеть им (и ожидать, что это обращение не будет длиться дольше, чем ресурс существует).

Существует четвертый тип, разновидность необработанных указателей для shared_ptr, называемый weak_ptr. Вы используете это для ссылки на shared_ptr, фактически не имея его; Затем вы можете проверить, находится ли объект еще там, и использовать его.

8 голосов
/ 01 декабря 2011

Единственный не имеющий смарт-указатель в стандартной библиотеке - std::weak_ptr.Тем не менее, чтобы использовать его, фактический владелец объекта должен содержать указатель в std::shared_ptr.

Я предполагаю, что вы использовали std::unique_ptr для них ранее.Если вы преобразуете их в shared_ptr сейчас, вы получите преимущество, заключающееся в том, что ваши не принадлежащие указатели могут знать, что потерянный указатель-владелец является эталонным, в то время как необработанные указатели могут быть оставлены висящими без какой-либо возможности для не-владеющего компонента обнаружить это.,Тем не менее, shared_ptr повлечет за собой (очень?) Небольшие потери производительности и памяти по сравнению с unique_ptr.

. Лично я рекомендую использовать один shared_ptr и много weak_ptr с вместо одного unique_ptr имного raw-указателей в общем случае и используйте unique_ptr, если у вас действительно есть проблема с производительностью!

...