общий_птр:для чего это используется
-
19-08-2019 - |
Вопрос
Я часто использую 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 не позволит объекту быть уничтоженным, пока не будут освобождены все ссылки на него.