Совместное владение:
Принятые стандарты shared_ptr
и weak_ptr
в значительной степени аналогичны их аналогам Boost .Используйте их, когда вам нужно поделиться ресурсом и не знать, какой из них станет последним живым.Используйте weak_ptr
для наблюдения общего ресурса, не влияя на его время жизни, чтобы не прерывать циклы.Циклы с shared_ptr
обычно не должны происходить - два ресурса не могут владеть друг другом.
Обратите внимание, что Boost дополнительно предлагает shared_array
, что может быть подходящей альтернативой shared_ptr<std::vector<T> const>
.
Далее, Boost предлагает intrusive_ptr
, которые являются легковесным решением, если ваш ресурс уже предлагает управление с подсчетом ссылок и вы хотите адаптировать его к принципу RAII.Этот стандарт не был принят.
Уникальное владение:
Повышение также имеет scoped_ptr
, который не подлежит копированию и для которого вы можетене указывать удалитель.std::unique_ptr
означает boost::scoped_ptr
на стероидах и должно быть вашим выбором по умолчанию, когда вам нужен умный указатель .Он позволяет вам указать удалитель в аргументах шаблона и является подвижным , в отличие от boost::scoped_ptr
.Он также полностью применим в контейнерах STL, если вы не используете операции, для которых нужны копируемые типы (очевидно).
Обратите внимание, что Boost имеет версию массива: scoped_array
, который стандарт унифицирует, требуя std::unique_ptr<T[]>
частичной специализации, которая будет delete[]
указатель вместо delete
его (с default_delete
r).std::unique_ptr<T[]>
также предлагает operator[]
вместо operator*
и operator->
.
Обратите внимание, что std::auto_ptr
по-прежнему в стандарте, но устарело .§D.10 [depr.auto.ptr]
Шаблон класса auto_ptr
устарел.[ Примечание: Шаблон класса unique_ptr
(20.7.1) обеспечивает лучшее решение. —конечная заметка ]
Нет владения:
Использовать тупые указатели (необработанные указатели) или ссылки для не владеющих ссылками к ресурсам, и когда вы знаете, что ресурс переживет ссылающийся объект / область.Предпочитайте ссылки и используйте необработанные указатели, когда вам нужна обнуляемость или возможность сброса.
Если вы хотите не принадлежащую ссылку на ресурс, но не знаете, будет ли ресурс переживать объект, который на него ссылается, упакуйтересурс в shared_ptr
и используйте weak_ptr
- вы можете проверить, если родительский shared_ptr
жив с lock
, который вернет ненулевое shared_ptr
, если ресурс все еще существует.Если вы хотите проверить, мертв ли ресурс, используйте expired
.Оба могут показаться похожими, но сильно отличаются друг от друга в условиях одновременного выполнения, так как expired
гарантирует только возвращаемое значение для этого единственного оператора.Кажущийся невинным тест, такой как
if(!wptr.expired())
something_assuming_the_resource_is_still_alive();
, является потенциальным условием гонки.