Shared_ptr: для чего он используется

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

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

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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
4
0
2 335
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

AFAIK a shared_ptr is only useful if different threads are going to be accessing the same data

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

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

Ответ принят как подходящий

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

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

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

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

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

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

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

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

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

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