I can understand why dynamic_cast does work in this case :
#include <iostream>
struct A{
virtual ~A() = default;
};
struct B {
virtual ~B() = default;
};
struct C : A, B{};
void f(const A &a) {
if(auto p = dynamic_cast<const B*>(&a))
std::cout << "a is a B" << std::endl;
}
int main() {
f(C{});
return 0;
}
But why if you remove the polymorphism from B it still works :
#include <iostream>
struct A{
virtual ~A() = default;
};
struct B {
};
struct C : A, B{};
void f(const A &a) {
if(auto p = dynamic_cast<const B*>(&a))
std::cout << "a is a B" << std::endl;
}
int main() {
f(C{});
return 0;
}
Is it because dynamic_cast must only know the real type of the object you give has a parameter (as dynamic_cast<void*>
/ typeid would do), and after it knows the real type, it knows if the type is derived from a non polymorphic base?
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 .
Yes, dynamic_cast is a code smell, but so is adding functions that try to make it look like you have a good polymorphic interface but are actually equal to a dynamic_cast i.e. stuff like can_put_on_board .
While typeid + static_cast is faster than dynamic_cast , not having to switch on the runtime type of the object is faster than any of them. Save this answer.
If the cast is successful, dynamic_cast returns a value of type new-type. If the cast fails and new-type is a pointer type, it returns a null pointer of that type. If the cast fails and new-type is a reference type, it throws an exception that matches a handler of type std::bad_cast.
According to the Standard ([expr.dynamic.cast]p6) it is the object you cast should have a polymorphic type, not the one you trying to cast to.
And it is absolutely logical if you think about it. dynamic_cast
requires some info to make casting (RTTI) and this info is tied to polymorphic types. So it doesn't matter if the parents of the type are polymorphic or not, the info about this class is right here. You do not need to know other's class RTTI to cast this object to it. You just need to know if this object is actually in some relationship with what you want to convert it to.
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