Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ dynamic_cast

class CBase { };
class CDerived: public CBase { };

CBase     b; 
CBase*    pb;
CDerived  d; 
CDerived* pd;

pb = dynamic_cast<CBase*>(&d);     // ok: derived-to-base
pd = dynamic_cast<CDerived*>(&b);  // wrong: base-to-derived

I know the "base to derived " cast is wrong. But what is the inside reason of it? What is logical reason inside? It's hard to remember this without more explanation I guess. thank you!

like image 499
user658266 Avatar asked Jan 28 '26 17:01

user658266


2 Answers

First, CBase must be polymorphic in order for you to use dynamic_cast here (that is, it must have at least one virtual member function). Otherwise, you can't use dynamic_cast.

That said, the cast of &b to CDerived* is not wrong: pd will be a null pointer.

dynamic_cast has the useful property that when the cast fails (that is, if the object pointed to by the pointer isn't of the target type), it yields a null pointer. This allows you to test the actual type of an object. For example:

CBase b;
CDerived d;

CBase* pb = &b;
CBase* pd = &d;

CDerived* xb = dynamic_cast<CDerived*>(pb); // xb is null!
CDerived* xd = dynamic_cast<CDerived*>(pd); // xd points to d!

Your code would have been incorrect if you had used static_cast, since it casts without performing any runtime type check, which means there is no way to test whether the cast succeeded. If you ever need to cast down a class hierarchy and you don't know for certain whether the object is of the derived type to which you are trying to cast, you must use dynamic_cast.

like image 84
James McNellis Avatar answered Jan 31 '26 07:01

James McNellis


For the derived to base conversion, you don't need (and generally don't want) to specify a cast explicitly at all:

CDerived d;
CBase *pb = &d;   // perfectly fine

The base to derived cast isn't really wrong, though you'd generally prefer to avoid it. The reason behind that is fairly simple: a pointer to base could be pointing to an actual base object or anything derived from it. If you're going to down-cast like this, you generally need to check whether the conversion succeeded. In the specific case you've given, it won't succeed, so what gets assigned (the result of the dynamic_cast) will simply be a null pointer.

Most of the time, you'd prefer to specify a complete interface to objects of the class in the base class, so you rarely have much need for downcasts.

like image 37
Jerry Coffin Avatar answered Jan 31 '26 07:01

Jerry Coffin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!