Вопрос

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

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

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

Это было полезно?

Решение

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

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

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

Другие советы

  

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

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

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

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

  • scoped_ptr предназначен для "Выделение ресурсов — это инициализация" и не подлежит копированию (его нельзя использовать совместно с другими экземплярами, а право собственности не может быть передано)
  • shared_ptr предназначен для автоматического освобождения памяти при ее совместном использовании несколькими сторонами.
  • auto_ptr можно копировать (и передает право собственности при назначении)

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top