Интеллектуальные указатели: кто владеет объектом? [закрытый]

C++ - все о владении памяти - иначе семантика владения.

Это - ответственность владельца блока динамично выделенной памяти для освобождения той памяти. Таким образом, вопрос действительно становится, кто владеет памятью.

В C++ владение документируется типом, необработанный указатель перенесен внутри таким образом в хорошей программе C++ (IMO), очень редко (редкий, не никогда) видеть необработанные розданные указатели (поскольку необработанные указатели не имеют никакого выведенного владения таким образом, мы не можем сказать, кто владеет памятью, и таким образом без тщательного чтения документации Вы не можете сказать, кто ответственен за владение).

С другой стороны редко видеть необработанные указатели, сохраненные в классе, каждый необработанный указатель хранится в его собственной обертке интеллектуального указателя. (N.B.: Если Вы не владеете объектом, Вы не должны хранить его, потому что Вы не можете знать, когда он выйдет из объема и уничтожается.)

Так вопрос:

  • С каким владением, семантическим, люди столкнулись?
  • Какие стандартные классы используются для реализации их семантика?
  • В каких ситуациях Вы находите их полезными?

Позволяет сохраняют 1 тип семантического владения на ответ, таким образом, за них можно проголосовать вверх и вниз индивидуально.

Сводка:

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

std::auto_ptr<T>:

Единственный человек владеет объектом. Передача права собственности позволяется.

Использование: Это позволяет Вам определять интерфейсы, которые показывают явную передачу права собственности.

boost::scoped_ptr<T>

Единственный человек владеет объектом. Передача права собственности НЕ позволяется.

Использование: Используемый для показа явного владения. Объект будет уничтожен деструктором или, когда явно сброшено.

boost::shared_ptr<T> (std::tr1::shared_ptr<T>)

Несколько владение. Это - простая ссылка считаемый указатель. Когда подсчет ссылок достигает нуля, объект уничтожается.

Использование: Когда объект может иметь несколько верхних мячей со временем жизни, которое не может быть определено во время компиляции.

boost::weak_ptr<T>:

Используемый с shared_ptr<T> в ситуациях, где цикл указателей может произойти.

Использование: Используемый, чтобы мешать циклам сохранить объекты, когда только цикл поддерживает общий refcount.

113
задан Marc.2377 5 October 2019 в 05:12
поделиться

0 ответов

Для меня эти 3 вида удовлетворяют большинство моих потребностей:

shared_ptr - считаемый на ссылку, освобождение, когда счетчик достигает нуля

weak_ptr - то же как выше, но это - 'ведомое устройство' для shared_ptr, не может освободить

auto_ptr - когда создание и освобождение происходят в той же функции, или когда объект нужно считать one-owner-only когда-либо. Когда Вы присваиваете один указатель на другого, вторые 'кражи' объект сначала.

у меня есть своя собственная реализация для них, но они также доступны в Boost.

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

существует другой вид указателя, что я использую это, я звоню hub_ptr. Именно, когда у Вас есть объект, должно быть доступным от объектов, вложенных в нем (обычно как виртуальный базовый класс). Это могло быть решено путем передачи weak_ptr им, но это не имеет shared_ptr к себе. Поскольку это знает, что эти объекты не жили бы дольше, чем он, это передает hub_ptr им (это - просто шаблонная обертка к регулярному указателю).

20
ответ дан Failed Scientist 24 November 2019 в 02:45
поделиться

Простая Модель

C++ В большинстве модулей, я видел, по умолчанию, что предполагалось, что получение указателей было не владение получения. На самом деле функции/методы, отказывающиеся от владения указателя, были и очень редки и явно выразили тот факт в своей документации.

Эта модель предполагает, что пользователь является владельцем только того, что он явно выделяет . От всего остального автоматически избавляются (в выходе объема, или через RAII). Это - подобная C модель, расширенная фактом, большинство указателей принадлежит объектам, которые освободят их автоматически или, когда необходимый (при упомянутом разрушении объектов, главным образом), и что срок службы объектов предсказуем (RAII является Вашим другом, снова).

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

  • необработанные указатели
  • станд.:: повышение auto_ptr
  • :: scoped_ptr

Умная Резкая Модель

C++ В коде, полном интеллектуальных указателей, пользователь может надеяться проигнорировать время жизни объектов. Владелец никогда не является пользовательским кодом: Это - сам интеллектуальный указатель (RAII, снова). проблема состоит в том, что циклические ссылки смешались со ссылкой, считаемые интеллектуальные указатели могут быть смертельны , таким образом, необходимо иметь дело оба и с совместно использованными указателями и со слабыми указателями. Таким образом, у Вас есть все еще владение для рассмотрения (слабый указатель ни на что не мог указать, даже если его преимущество перед необработанным указателем состоит в том, что это может сказать Вам так).

  • повышение:: повышение shared_ptr
  • :: заключение

    weak_ptr

, Неважно, модели, которые я описываю, , если исключение, получая указатель не не получение его владения и , все еще очень важно знать, кто владеет кто . Даже для C++ кодируют в большой степени использование ссылок и/или интеллектуальных указателей.

23
ответ дан paercebal 24 November 2019 в 02:45
поделиться

Не имейте совместно использованного владения. Если Вы делаете, удостоверьтесь, что это только с кодом, которым Вы не управляете.

, Который решает 100% проблем, так как они вынуждают Вас понять, как все взаимодействует.

10
ответ дан Tim Cooper 24 November 2019 в 02:45
поделиться
  • Общее Владение
  • повышение:: shared_ptr

, Когда ресурс совместно используется несколькими объектами. Повышение shared_ptr использует подсчет ссылок, чтобы удостовериться, что ресурс освобожден, когда все - finsihed.

2
ответ дан Martin York 24 November 2019 в 02:45
поделиться

std::tr1::shared_ptr<Blah> довольно часто Ваш лучший выбор.

2
ответ дан Matt Cruikshank 24 November 2019 в 02:45
поделиться

От повышения, существует также контейнер указателя библиотека. Они немного более эффективны и легче использовать, чем стандартный контейнер интеллектуальных указателей при только использовании объектов в контексте их контейнера.

В Windows, существуют указатели COM (IUnknown, IDispatch и друзья), и различные интеллектуальные указатели для обработки их (например, ATL CComPtr и интеллектуальные указатели, автоматически сгенерированные оператором "импорта" в Visual Studio на основе класс _com_ptr ).

2
ответ дан Ryan Ginstrom 24 November 2019 в 02:45
поделиться

Я не думаю, что когда-либо имел возможность совместно использовать владение в своем дизайне. На самом деле от вершины моей головы единственный допустимый случай, о котором я могу думать, является шаблоном В наилегчайшем весе.

1
ответ дан Nemanja Trifunovic 24 November 2019 в 02:45
поделиться
  • Один Владелец
  • повышение:: scoped_ptr

, Когда необходимо выделить память динамично, но хотеть быть уверенными, что это освобождено на каждой точке выхода блока.

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

1
ответ дан Pieter 24 November 2019 в 02:45
поделиться

Существует другая часто используемая форма единственного передаваемого владельца, и желательно к auto_ptr, потому что она избегает проблем, вызванных auto_ptr безумное повреждение семантики присвоения.

я не говорю ни о ком другом, чем swap. Любой тип с подходящим swap функция может быть задумана как умная ссылка к некоторому содержанию, которым это владеет до тех пор, пока владение передается другому экземпляру того же типа путем свопинга их. Каждый экземпляр сохраняет свои идентификационные данные, но связывается с новым содержанием. Это похоже безопасно rebindable ссылка.

(Это - умная ссылка, а не интеллектуальный указатель, потому что Вы не должны явно разыменовывать его для достигания содержания.)

Это означает, что auto_ptr становится менее необходимым - только необходимо заполнить разрывы, где типы не имеют пользы swap функция. Но все контейнеры станд. делают.

1
ответ дан Daniel Earwicker 24 November 2019 в 02:45
поделиться

yasper:: ptr является легким весом, повышением:: shared_ptr как альтернатива. Это работает хорошо в моем (на данный момент) маленький проект.

В веб-странице в http://yasper.sourceforge.net/ это описано следующим образом:

, Почему запись другой интеллектуальный указатель C++? Там уже существуют несколько высококачественных реализаций интеллектуального указателя для C++, наиболее заметно пантеон указателя Повышения и SmartPtr Loki. Для хорошего сравнения реализаций интеллектуального указателя и когда их использование будет соответствующим, считайте Herb Sutter Новый C++: Умные (er) Указатели. В отличие от расширяемых функций других библиотек, Yasper является узко сфокусированным указателем подсчета ссылок. Это соответствует тесно shared_ptr Повышения и политикам Loki RefCounted/AllowConversion. Yasper позволяет программистам на C++ забывать об управлении памятью, не представляя большие зависимости Повышения или имея необходимость узнать о сложных шаблонах политики Loki. Философия

* small (contained in single header)
* simple (nothing fancy in the code, easy to understand)
* maximum compatibility (drop in replacement for dumb pointers)

последняя точка может быть опасной, так как yasper разрешает опасный (все же полезный) действия (такие как присвоение на необработанные указатели и ручной выпуск) запрещенный другими реализациями. Будьте осторожны, только используйте те функции, если Вы знаете то, что Вы делаете!

1
ответ дан Hernán 24 November 2019 в 02:45
поделиться
  • Один Владелец: иначе удалите на Копии
  • станд.:: auto_ptr

, Когда создатель объекта хочет явно вручить владение кому-то еще. Это - также способ документировать в коде, я даю это Вам, и я больше не отслеживаю его, так удостоверьтесь, что Вы удаляете его, когда Вы закончены.

0
ответ дан Martin York 24 November 2019 в 02:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: