can anyone tell what are the exact checks that dynamic_cast does? how can there be a scenario where I can downcast to the grandson and fail to downcast to the son? (using normal inheritance and not diamond)
CodePudding user response:
what are the exact checks that dynamic_cast does?
It checks whether the dynamic type of the pointed object is actually the cast target type (or a type derived from it) or not.
how can there be a scenario where I can downcast to the grandson and fail to downcast to the son?
Cast to a child class can be ambiguous, in which case the cast won't work.
CodePudding user response:
what are the exact checks that dynamic_cast does?
consider the following line of code
dynamic_cast<t*>(a)
if a
is of type t*
or an accessible base class of t
, the result is exactly as if we assigned a
to t*
.
dynamic_cast can be used to deal with the case in which the the correctness of the conversion cannot be determined by the compiler, In that case, dynamic_cast looks at the object pointed to by a
. If that object is of class t
or has a unique base class of type t
, then dynamic_cast returns a pointer of type t*
to that object else 0
is returned.
And If we want a down cast or cross cast a dynamic_cast
would require a pointer or a reference to a polymorphic type.
CodePudding user response:
There are two situations where dynamic_cast
does something that static_cast
doesn't, which overlap in complex inheritance hierachies.
Firstly it has defined behaviour if you don't have an object of the target type.
class Base { virtual ~Base() = default; };
class Derived : public Base {};
Base b;
Derived d;
Base * b1 = &d; // Points to Base subobject
Derived * d1 = static_cast<Derived *>(b1); // Ok, equal to &d
Base * b2 = &b;
// Derived * d2 = static_cast<Derived *>(b2); // Undefined behaviour
Derived * d3 = dynamic_cast<Derived *>(b2); // Ok, d3 is null
Secondly you can cast "unrelated" types if you have an object that inherits both.
class Left { virtual ~Left() = default; };
class Right { virtual ~Right() = default; };
class Mixed : public Left, public Right { };
Mixed m;
Left * l = &m; // Points to Left subobject of m
// Right * r1 = static_cast<Right *>(l); // compile error, unrelated types
Right * r2 = dynamic_cast<Right *>(l); // Ok, r points to Right subobject of m