15

I have a problem using a shared_ptr of a base class, I can't seem to be able to call the derived class's methods when dereferencing it. I believe code will be more verbose than me:

class Base : public boost::enable_shared_from_this<Base>
{
  public:
    typedef  boost::shared_ptr<BabelNet> pointer;
};

class Derived : public Base
{
  public:
     static pointer  create()
                {
                        return pointer(new Derived);
                }
     void             anyMethod()
     {
        Base::pointer foo = Derived::create();
        // I can't call any method of Derived with foo
        // How can I manage to do this ?
        // is dynamic_cast a valid answer ?
        foo->derivedMethod(); // -> compilation fail
     }

};
Null
  • 1,950
  • 9
  • 30
  • 33
HolyLa
  • 153
  • 1
  • 1
  • 4

4 Answers4

19

see static_cast with boost::shared_ptr?

you'll need to use dynamic_pointer_cast to get the appropriate shared_ptr instantiation. (corresponding to a dynamic_cast)

Community
  • 1
  • 1
lijie
  • 4,811
  • 22
  • 26
  • 1
    Why not `static_pointer_cast`? I guess maybe the example isn't representative of the real code, but the example doesn't need a dynamic cast (because the object is of the target type), and doesn't allow one (because neither class has any virtual functions). – Steve Jessop Nov 25 '10 at 14:03
  • I put `dynamic_pointer_cast` because of the title of the post, actually. But yes, in his code, a `static_pointer_cast` will do. – lijie Nov 25 '10 at 14:48
  • Right, thanks to you I've found an interesting article: http://nealabq.com/blog/2008/11/26/pointer_cast/ if I just use a shared_ptr to the derived_class, I can pass it as a shared_ptr to the base class, neat. – HolyLa Nov 25 '10 at 15:13
4

Shared pointer or not, when you have a pointer to a Base, you can only call member functions from Base.

If you really need to dynamic_cast, you can use dynamic_pointer_cast from boost, but chances are that you shouldn't. Instead, think about your design : Derived is a Base, and this is an extremely strong relationship, so think carefully about Base interface and if the concrete type really has to be known.

icecrime
  • 74,451
  • 13
  • 99
  • 111
1

If derivedMethod is not declared in base class (virtual or not), then it is normal that the compilation would fail. The shared ptr knows and uses the base class (through the pointer it holds), and knows nothing about the derived class and its specific methods.

Cătălin Pitiș
  • 14,123
  • 2
  • 39
  • 62
  • If the pointer was a typedef of the derived class, could it be upcasted so that an external class can only know about Base::pointer ? – HolyLa Nov 25 '10 at 14:12
0

Your code wouldn't work even with raw pointers.

You need either to declare derivedMethod() method even in base class or to have a pointer to aDerived object.

Simone
  • 11,655
  • 1
  • 30
  • 43