74

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 Derived();
Derived* d = static_cast<Derived*>(b);

when using shared_ptr?

boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = ???
peterchen
  • 40,917
  • 20
  • 104
  • 186
Frank
  • 64,140
  • 93
  • 237
  • 324

4 Answers4

106

Use boost::static_pointer_cast:

boost::shared_ptr<Base> b(new Derived());
boost::shared_ptr<Derived> d = boost::static_pointer_cast<Derived>(b);
peterchen
  • 40,917
  • 20
  • 104
  • 186
Frank
  • 64,140
  • 93
  • 237
  • 324
  • 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. – Frank Mar 09 '09 at 02:52
  • 4
    `boost::static_pointer_cast(b)` could also be used as `Base` is implicit. – dalle Mar 26 '10 at 21:32
  • 5
    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 Apr 16 '10 at 15:07
  • 1
    is 'boost::shared_ptr d = boost::static_pointer_cast(b);' VALID? as b contains memory only for base class - 'b(new Base());' – Uylenburgh Apr 24 '14 at 11:10
  • @Oleksandra, yes - but it's the same mistake as in OP. Edited Frank's post to that effect. – peterchen Aug 12 '14 at 09:51
22

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).

Michael Kristofik
  • 34,290
  • 15
  • 75
  • 125
3

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
  • 204,818
  • 23
  • 294
  • 489
  • 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 Mar 11 '09 at 07:43
  • 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 Jul 17 '09 at 14:09
  • ...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 Jul 17 '09 at 14:09
  • It is possible that dynamic_cast not working if the Derived class is located in another library then Base class. – Andrei Bica Aug 10 '11 at 12:41
2

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
  • 37,086
  • 11
  • 109
  • 136