Вам нужно использовать static_pointer_cast
:
struct B { virtual ~B() { } };
struct D : B { };
shared_ptr<B> bp(new D);
shared_ptr<D> dp(static_pointer_cast<D>(b));
(Есть также dynamic_pointer_cast
и const_pointer_cast
для выполнения динамического и константного приведения соответственно.)