Search code examples
c++castingshared-ptr

Why is casting on shared_ptr like this?


I have seen one of the old posts on the topic. Due to my new account and lack of reputation points, I cannot comment there; hence, I am making this post.

I was looking in the past for a way to cast shared pointers from one type to another (from base to derived) in order to access some private members on the derived-side. I know its best to avoid downcasting, but this was the framework... Anyway, I saw the answer on the original post was:

std::shared_ptr<A> ap = ...;
dynamic_cast<B&>(*ap).b_function();
if (B* bp = dynamic_cast<B*>(ap.get()) 

Now, in the command: dynamic_cast<B&>(*ap).b_function() I understand that the de-referencing symbol here gives us a reference to the pointed object by the shared_ptr . My question is why do we need a reference on the B (i.e. B&)? Couldn't we make it work as:

B& Bref = dynamic_cast<B>(*ap);
Bref.b_function();

I am not very familiar with templates (like shared_ptr is implemented), so I guess its my lack of knowledge on the matter. Could someone please explain to me the meaning behind the & on this context and why the alternative I gave doesn't work?


Solution

  • The point is that a cast to a non-pointer/reference type is always a conversion in C++. You get the converted value which is distinct from the original value. It is a new local object with its own place in memory. Consequently, any change to this copy will not affect the original value at all.

    In the case of classes A and B, the cast (B)a would construct the new object by calling the B::B(A&) constructor of class B.


    Of course, such conversions is not what dynamic_cast<> is supposed to be used for, so dynamic_cast<> with a non-pointer/reference type is forbidden by the standard.