views:

2380

answers:

4

What is the equivalent of a static_cast with boost::shared_ptr?

In other words, how do I have to rewrite the following

Base* b = new Base();
Derived* d = static_cast<Derived*>(b);

when using shared_ptr?

boost::shared_ptr<Base> b(new Base());
boost::shared_ptr<Derived> d = ???
+14  A: 

Use boost::static_pointer_cast:

boost::shared_ptr<Base> b(new Base());
boost::shared_ptr<Derived> d = boost::static_pointer_cast<Derived, Base>(b);
I tried casting and rewrapping the raw pointer at first, not knowing about static_pointer_cast. So I think it's useful to have this info on stackoverflow.
`boost::static_pointer_cast<Derived>(b)` could also be used as `Base` is implicit.
dalle
I just thought I'd share that if you are using this and the Derived class hasn't been fully included (i.e. it's only been forward declared) you get the very unhelpful "invalid type conversion: "Base *" to "Derived *"". It took me quite a long time staring at the screen before I figured it out :)
Jamie Cook
+7  A: 

There are three cast operators for smart pointers: static_pointer_cast, dynamic_pointer_cast, and const_pointer_cast. They are either in namespace boost (provided by <boost/shared_ptr.hpp>) or namespace std::tr1 (provided either by Boost or by your compiler's TR1 implementation).

Kristo
A: 

As a comment: if Derived does in fact derive from Base, then you should use a dynamic_pointer_cast rather than static casts. The system will have a chance of detecting when/if your cast is not correct.

David Rodríguez - dribeas
The system can't detect this if Base doesn't have virtual members though. Dynamic_cast is only magical on classes that have virtual members.
Aaron
Also there is a performance hit. If you really know that the cast should always succeed, static_cast will work with no runtime overhead.
Joseph Garvin
...no runtime overhead *usually*. I can't recall the details but with virtual multiple inheritance or some other corner case there is technically overhead, but still less than dynamic_cast.
Joseph Garvin
A: 

It is worth to mention that the there is difference in the number of casting operators provided by Boost and implementations of TR1.

The TR1 does not define the third operator const_pointer_cast()

mloskot