Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting - Why Should I do it for Upcasting

I have been reading some other threads on this site, and they mention how dynamic_cast and static_cast are both safe for upcasting.

Why are these even required for upcasting?

For example, if class B is derived from A, then

A * ptr = new B ();

still works, and behaves like an object of type A. (I am also from a Java background where conversion for upcasting is unnecessary.

I also read on this site that dynamic_cast is not needed for downcasting [in question "When should static_cast, dynamic_cast, const_cast and reinterpret_cast be used?"] . Again, I would think that casting is only really necessary when you are downcasting since upcasting occurs automatically.

Where am I wrong?

like image 537
user929404 Avatar asked Oct 04 '22 06:10

user929404


2 Answers

If you have complex inheritance hierarchies, the default upcast behavior might not work. Consider for example:

struct A {};
struct B : A {};
struct C : A {};
struct D : B, C {};

In that hierarchy an object of type D has two different bases of type A. The conversion from D* to A* is ambiguous. For this type of cases you can force going through an intermediate step

A *p = static_cast<B*>(d);   // Give me the 'A' subobject within 'B'

Similarly, if there is a function with multiple overloads that can take either the base or the derived type and you need to call the version taking the base type (note: code smell here!) then you can use the cast to direct overload resolution. Again, if you need to direct overload resolution, you are probably doing something else wrong.

Other than corner cases (i.e. when the default upcast does not work) there is really no reason to explicitly use a cast operation, and I would actually advice against it, as casts should be a warning light and overusing them might make them normal and not raise alarms when reading code.

like image 175
David Rodríguez - dribeas Avatar answered Oct 10 '22 03:10

David Rodríguez - dribeas


In case of multiple inheritance (which Java doesn't really have) you will possibly adjust your "this" pointer. In that case a reinterpret_cast is not safe, which is what they are trying to emphasize by saying that static_cast and dynamic_cast are safe.

As a small note, in an investigation in a codebase that was to be ported to Android-without-dynamic_cast I found 127 dynamic_casts, of which 122 were not actually necessary. This was code written by people that were OK to very proficient in C++.

like image 25
dascandy Avatar answered Oct 10 '22 04:10

dascandy