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





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) в основном заключается в семантике копирования.
Shared_ptr - это тип интеллектуального указателя, который выполняет подсчет ссылок. Если у объекта только один владелец (частый случай), то scoped_ptr - правильное решение. Если объект может совместно использоваться несколькими частями кода, то shared_ptr не позволит уничтожить объект, пока не будут освобождены все ссылки на него.
Еще одно важное различие между shared_ptr и scoped_ptr заключается в том, что только shared_ptr работает с weak_ptr. Слабые указатели используются для прерывания циклов общих указателей, тем самым избегая утечек памяти, но weak_ptr можно использовать и для большего.
Общие и слабые указатели могут использоваться для обозначения разницы между ссылками, владеющими и не владеющими. Однозначное владение данными приводит к более чистому дизайну, поэтому, когда возможные объекты данных должны принадлежать один другому объекту через shared_ptr. Все другие долгоживущие ссылки на объекты данных должны быть слабыми указателями, свидетельствующими о том, что они не владеют данными. Каждый раз, когда какие-либо модули, не являющиеся собственниками, обращаются к данным, им необходимо преобразовать weak_ptr в shared_ptr, после чего они могут обнаружить, что объект данных больше не существует. Однако, хотя модули, не владеющие данными, обращаются к объекту данных, они удерживают его через временный shared_ptr, обеспечивая безопасную работу, даже если объект-владелец должен был освободить данные.