Be cautious when using standard bf(C++) style casts in combination with
tt(shared_ptr) objects. Consider the following two classes:
        verb(
    struct Base
    {};
    struct Derived: public Base
    {};
        )

    As with tt(unique_ptr), when defining a tt(shared_ptr<Base>) to store a
newly allocated tt(Derived) class object, the returned tt(Base *) may be cast
to a tt(Derived *) using a tt(static_cast): polymorphism isn't required, and
when resetting the tt(shared_ptr) or when the tt(shared_ptr) goes out of
scope, no slicing occurs, and tt(Derived)'s destructor is called (cf. section
ref(UNIQUEPTR)).

    Of course, a tt(shared_ptr<Derived>) can easily be defined. Since a
tt(Derived) object is also a tt(Base) object, a pointer to tt(Derived) can
be considered a pointer to tt(Base) without using casts, but a tt(static_cast)
could be used to force the interpretation of a tt(Derived *) to a tt(Base *):
        verb(
    Derived d;
    static_cast<Base *>(&d);
        )

    However, a plain tt(static_cast) cannot be used when initializing a shared
pointer to a tt(Base) using the tt(get) member of a shared pointer to a
tt(Derived) object. The following code snipped eventually results in an
attempt to delete the dynamically allocated tt(Base) object twice:
        verb(
    shared_ptr<Derived> sd{ new Derived };
    shared_ptr<Base> sb{ static_cast<Base *>(sd.get()) };
        )
    Since tt(sd) and tt(sb) point at the same object tt(~Base) will be called
for the same object when tt(sb) goes out of scope and when tt(sd) goes out of
scope, resulting in premature termination of the program due to a
 emi(double free) error.

    These errors can be prevented using casts that were specifically designed
for being used with tt(shared_ptrs). These casts use specialized constructors
that create a tt(shared_ptr) pointing to memory but shares ownership (i.e.,
a reference count) with an existing tt(shared_ptr). These special casts are:
    itemization(
    ithtq(static_pointer_cast)
        (std::static_pointer_cast<Base>(std::shared_ptr<Derived> ptr))
        (A tt(shared_ptr) to a tt(Base) class object is returned. The returned
tt(shared_ptr) refers to the base class portion of the tt(Derived) class to
which the tt(shared_ptr<Derived> ptr) refers. Example:
        verb(
shared_ptr<Derived> dp{ new Derived };
shared_ptr<Base> bp = static_pointer_cast<Base>(dp);
        )
        )

    ithtq(const_pointer_cast)
        (std::const_pointer_cast<Class>(std::shared_ptr<Class const> ptr))
        (A tt(shared_ptr) to a tt(Class) class object is returned. The
returned tt(shared_ptr) refers to a non-const tt(Class) object whereas the
tt(ptr) argument refers to a tt(Class const) object. Example:
        verb(
shared_ptr<Derived const> cp{ new Derived };
shared_ptr<Derived> ncp = const_pointer_cast<Derived>(cp);
        )
        )

    ithtq(dynamic_pointer_cast)
        (std::dynamic_pointer_cast<Derived>(std::shared_ptr<Base> ptr))
        (A tt(shared_ptr) to a tt(Derived) class object is returned. The
tt(Base) class must have at least one virtual member function, and the class
tt(Derived), inheriting from tt(Base) may have overridden tt(Base)'s virtual
member(s). The returned tt(shared_ptr) refers to a tt(Derived) class object if
the dynamic cast from tt(Base *) to tt(Derived *) succeeded. If the dynamic
cast did not succeed the tt(shared_ptr)'s tt(get) member returns 0.  Example
(assume tt(Derived) and tt(Derived2) were derived from tt(Base)):
        verb(
shared_ptr<Base> bp(new Derived());
cout << dynamic_pointer_cast<Derived>(bp).get() << ' ' <<
        dynamic_pointer_cast<Derived2>(bp).get() << '\n';
        )
    The first tt(get) returns a non-0 pointer value, the second tt(get)
returns 0.
        )
    )
