Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic_cast on non polymorphic types

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?

like image 679
Antoine Morrier Avatar asked Sep 04 '18 16:09

Antoine Morrier


People also ask

What is the dynamic_cast operator used for?

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 .

Is dynamic_cast a code smell?

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 .

Is Static_cast faster than dynamic_cast?

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.

What is the behavior of dynamic_cast when down casting is detected on pointers?

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.


1 Answers

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.

like image 187
ixSci Avatar answered Oct 07 '22 08:10

ixSci