简体   繁体   中英

Trying to understand how dynamic_cast works

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)

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.

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM