Consider this simple hierarchy:
class Base { public: virtual ~Base() { } }; class Derived : public Base { };
Trying to downcast Base* p
to Derived*
is possible using dynamic_cast<Derived*>(p)
. I used to think dynamic_cast
works by comparing the vtable pointer in p
to the one in a Derived
object.
But what if we derive another class from Derived
? We now have:
class Derived2 : public Derived { };
In this case:
Base* base = new Derived2; Derived* derived = dynamic_cast<Derived*>(base);
We still get a successful downcast, even though the vtable pointer in Derived2
has nothing to do with a vtable pointer in Derived
.
How does it actually work? How can the dynamic_cast
know whether Derived2
was derived from Derived
(what if Derived
was declared in a different library)?
I am looking for specific details about how this actually works (preferably in GCC, but others are fine too). This question is not a duplicate of this question (which doesn't specify how it actually works).
static_cast − This is used for the normal/ordinary type conversion. This is also the cast responsible for implicit type coersion and can also be called explicitly. You should use it in cases like converting float to int, char to int, etc. dynamic_cast −This cast is used for handling polymorphism.
The primary purpose for the dynamic_cast operator is to perform type-safe downcasts. A downcast is the conversion of a pointer or reference to a class A to a pointer or reference to a class B , where class A is a base class of B .
The fact, that the cast is safe is known by the compiler at compile time. This means, that dynamic_cast does not need to use RTTI.
This cast is used for handling polymorphism. You only need to use it when you're casting to a derived class. This is exclusively to be used in inheritence when you cast from base class to derived class.
How can the
dynamic_cast
know whetherDerived2
was derived fromDerived
(what ifDerived
was declared in a different library)?
The answer to that is surprisingly simple: dynamic_cast
can know this by keeping this knowledge around.
When the compiler generates code it keeps around the data about the class hierarchies in some sort of table that dynamic_cast
can look up later. That table can be attached to the vtable pointer for easy lookup by the dynamic_cast
implementation. The data neeeded for typeid
for those classes can also be stored along with those.
If libraries are involved, this sort of thing usually requires these type information structures to be exposed in the libraries, just like with functions. It is possible, for example, to get a linker error that looks like "Undefined reference to 'vtable for XXX'" (and boy, are those annoying!), again, just like with functions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With