Вы должны понимать, что совместно используемые указатели реализованы с использованием счетчика ссылок, это означает, что если у вас есть циклы в графе указателей, то объекты не будут освобождены. То есть, если a указывает на b, а b указывает на a, но ничто не указывает на a или b, то ни a, ни b не будут освобождены, поскольку у них обоих счетчик ссылок равен 1.
Boost предоставляет слабые указатели, чтобы обойти это, что позволяет хранить указатель на общий объект без увеличения его счетчика ссылок. Слабые указатели обеспечивают уровень безопасности, поскольку попытка разыменования указателя после освобождения общего указателя вызовет исключение, а не сбой программы.
Общие указатели также довольно дороги (по крайней мере, по сравнению с необработанным указателем) с точки зрения производительности, но лучше использовать их, а затем удалять их, как только профилировщик обнаружит узкое место, а не использовать их повсеместно.
Кроме этого, да, они очень полезны для управления динамически размещаемыми объектами.
Редактировать: Еще один уловок (упомянутый на страницах поддержки) - избегать "временных" указателей shared_points:
func(A(), boost::shared_ptr<B>(new B));
потому что компилятору разрешено оптимизировать это как
tmp1 = new B;
tmp2 = A();
tmp3 = boost::shared_ptr<B>(tmp1)
func(tmp2,tmp3)
, что на первый взгляд может выглядеть нормально, но если A () генерирует исключение, то B выделяется, но shared_ptr еще не получил его, поэтому указатель никогда не освобождается.