Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Downcasting shared_ptr<Base> to shared_ptr<Derived>?

Tags:

c++

gcc

boost

Update: the shared_ptr in this example is like the one in Boost, but it doesn't support shared_polymorphic_downcast (or dynamic_pointer_cast or static_pointer_cast for that matter)!

I'm trying to initialize a shared pointer to a derived class without losing the reference count:

struct Base { }; struct Derived : public Base { }; shared_ptr<Base> base(new Base()); shared_ptr<Derived> derived;  // error: invalid conversion from 'Base* const' to 'Derived*' derived = base;   

So far, so good. I didn't expect C++ to implicitly convert Base* to Derived*. However, I do want the functionality expressed by the code (that is, maintaining the reference count while downcasting the base pointer). My first thought was to provide a cast operator in Base so that an implicit conversion to Derived could take place (for pedants: I would check that the down cast is valid, don't worry):

struct Base {   operator Derived* (); } // ... Base::operator Derived* () {   return down_cast<Derived*>(this); } 

Well, it didn't help. It seems the compiler completely ignored my typecast operator. Any ideas how I could make the shared_ptr assignment work? For extra points: what kind of type Base* const is? const Base* I understand, but Base* const? What does const refer to in this case?

like image 607
Lajos Nagy Avatar asked Aug 31 '09 16:08

Lajos Nagy


1 Answers

You can use dynamic_pointer_cast. It is supported by std::shared_ptr.

std::shared_ptr<Base> base (new Derived()); std::shared_ptr<Derived> derived =                std::dynamic_pointer_cast<Derived> (base); 

Documentation: https://en.cppreference.com/w/cpp/memory/shared_ptr/pointer_cast

Also, I don't recommend using cast operator in the base class. Implicit casting like this may become the source of bugs and errors.

-Update: If the type is not polymorphic, std::static_pointer_cast may be used.

like image 159
Masood Khaari Avatar answered Sep 22 '22 02:09

Masood Khaari