shared_ptr: для чего он используется - PullRequest
4 голосов
/ 05 декабря 2008

Я много использую boost :: scoped_ptr в своем коде, и это здорово, но я сейчас работаю с программным обеспечением, которое повсеместно использует shared_ptr, и мне интересно, что я что-то упустил.

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

Есть ли другие варианты использования?

Ответы [ 6 ]

7 голосов
/ 05 декабря 2008

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

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

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

7 голосов
/ 05 декабря 2008

AFAIK shared_ptr полезен только если разные темы будут доступ к тем же данным

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

Вы можете использовать scoped_ptr , если все, что вам нужно, это указатель, который удаляется, когда оставляется область, в которой он создан (либо по исключениям, либо goto для место снаружи, или с помощью нормального потока управления или какого-либо другого механизма). Если вы используете его таким образом, нет необходимости менять на shared_ptr.

2 голосов
/ 19 июля 2011

Другое важное различие между shared_ptr и scoped_ptr состоит в том, что только shared_ptr работает со слабым_ptr. Слабые указатели используются для прерывания циклов общих указателей, что позволяет избежать утечек памяти, но для этого можно использовать слабый_птр.

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

2 голосов
/ 18 апреля 2009

Разница между scoped_ptr и shared_ptr (и auto_ptr) в основном заключается в семантике копирования.

  • scoped_ptr для " Распределение ресурсов инициализируется " и не может быть скопировано (его нельзя использовать совместно с другими экземплярами, а право собственности не может быть передано)
  • shared_ptr для автоматического восстановления памяти при совместном использовании несколькими сторонами
  • auto_ptr копируется (и передает право собственности при назначении)
1 голос
/ 30 апреля 2009

shared_ptr - это умный тип указателя, который выполняет подсчет ссылок. Если у объекта есть только один владелец (частый случай), тогда scoped_ptr - правильное решение. Если объект может совместно использоваться несколькими частями кода, то shared_ptr не позволит объекту быть уничтоженным, пока не будут освобождены все ссылки на него.

1 голос
/ 05 декабря 2008

Как уже было сказано, shared_ptr - это совместное владение. Тем не менее, я бы сказал, что совместное владение, как правило, плохо (существуют исключения, такие как шаблон flyweight), и лучше определить владельца и поместить туда scoped_ptr.

...