-
Using polymorphism with boost::shared_ptr카테고리 없음 2010. 10. 21. 18:28반응형
http://itknowledgehub.com/development-integration/using-polymorphism-with-boostshared_ptr/
I’m currently in the final stages of converting a library from using raw
pointers to using boost::shared_ptr. This is mainly done to resolve
issues with pointer ownership rather than the outright prevention of
memory leaks, but the latter is a nice side effect of the former.The one problem that I ran into during this work was that the
library and its clients make rather heavy use of polymorphism. Of course
in 99% of the code that was fine as the objects were accessed through
pointers to base classes, but the last 1% was causing problems because
that part of the code contained lots of dynamic_cast statements. As these classes unfortunately needed to know the exact type
they were dealing with, there was no easy way around the use of these idioms, either. It probably isn’t news to most of the people
reading this blog that dynamic_cast and boost::shared_ptr don’t play
that nicely but I stepped right into that.The main issue is, unsurprisingly, that taking a pointer that is held
inside a boost::shared_ptr, dynamic_casting it down the hierarchy and
then stuffing it into another boost::shared_ptr is a good way to ensure
double deletion. Oops. So, if you see the following code you better get
the debugger out…boost::shared_ptr<A> something(new A(blah)); ... boost::shared_ptr<B> something_else(dynamic_cast<B>(something.get()));
So far so bad, but I couldn’t believe that something with a flaw that
obvious would be in the boost libraries. And of course, there is a
way around this – boost provides alternatives to the four C++ casts
with similar names that work on boost::shared_ptrs. You can find
these alternatives – which are really just wrappers around the C++
casts, but designed to work with the boost smart pointers – in the
include file boost/pointer_cast.hpp.. If you’re using smart pointers because you need polymorphic behaviour of, say, items stored in standard C++ containers, have a look at this page right now. If you don’t have the time or inclination to check the linked document right now, the management summary is: “The next time someone tells you that you can’t use
boost:.shared_ptr with dynamic_cast, point them in the direction of
boost::dynamic_pointer_cast”. Using boost::dynamic_pointer_cast would change the above example to:boost::shared_ptr<A> something(new A(blah)); ... boost::shared_ptr<B> something_else = boost::dynamic_pointer_cast<B>(something));
Problem solved.
반응형