cppannotations/yo/stl/sharedcasts.yo
2010-12-18 16:20:07 +00:00

72 lines
3.2 KiB
Text

Shared pointers cannot simply be cast using the standard bf(C++) style
casts. Consider the following two classes:
verb(
struct Base
{};
struct Derived: public Base
{};
)
A tt(shared_ptr<Derived>) can easily be defined. Since a tt(Derived) is
also a tt(Base) a pointer to a tt(Derived) can be cast to a pointer to a
tt(Base) using a static cast:
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 object pointer of a shared pointer to a
tt(Derived) object. I.e., the following statement will eventually result 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.
)
)