Я часто использую shared_ptr.
Поскольку Shared_ptr копируется по значению, вы можете понести затраты на копирование как значения указателя, так и счетчика ссылок, но если используется boost :: intrusive_ptr, счетчик ссылок должен быть добавлен в ваш класс, и нет дополнительные издержки выше, чем при использовании необработанного указателя.
Однако, по моему опыту, более чем в 99% случаев издержки на копирование экземпляров boost :: shared_ptr по всему коду незначительны. Обычно, как отметил С. А. Р. Хоар, преждевременная оптимизация не имеет смысла - большую часть времени другой код использует значительно больше времени, чем время для копирования небольших объектов. Ваш пробег может варьироваться. Если профилирование показывает, что копирование является проблемой, вы можете переключиться на навязчивые указатели.
Как уже отмечалось выше, циклы должны быть прерваны с помощью weak_ptr, иначе произойдет утечка памяти. Это произойдет со структурами данных, такими как некоторые графы, но если, например, вы создаете древовидную структуру, где листья никогда не указывают назад, вы можете просто использовать shared_pointers для узлов дерева без каких-либо проблем.
Правильное использование shared_ptr значительно упрощает код, облегчает его чтение и обслуживание. Во многих случаях их использование является правильным выбором.
Конечно, как уже упоминалось, в некоторых случаях использование scoped_ptr (или scoped_array) является правильным выбором. Если pointee не является общим, не используйте общие указатели!
Наконец, самый последний стандарт C ++ предоставляет шаблон std :: tr1 :: shared_ptr, который в настоящее время используется на большинстве платформ, хотя я не думаю, что существует тип навязчивого указателя для tr1 (или, скорее, но я не слышал об этом сам).