Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is dynamic_cast typically implemented?

Is the type check a mere integer comparison? Or would it make sense to have a GetTypeId virtual function to distinguishing which would make it an integer comparison?

(Just don't want things to be a string comparison on the class names)

EDIT: What I mean is, if I'm often expecting the wrong type, would it make sense to use something like:

struct Token
{
    enum {
        AND,
        OR,
        IF
    };
    virtual std::size_t GetTokenId() = 0;
};

struct AndToken : public Token
{
    std::size_t GetTokenId() { return AND; }
};

And use the GetTokenId member instead of relying on dynamic_cast.

like image 441
Billy ONeal Avatar asked Jul 23 '10 02:07

Billy ONeal


People also ask

How dynamic_cast is implemented in compiler?

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.

What is dynamic_cast 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 .

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

If the dynamic_cast is used on pointers, the null pointer value of type new-type is returned. If it was used on references, the exception std::bad_cast is thrown.

Does dynamic_cast required Rtti?

Note. You are permitted to use dynamic_cast without --rtti in cases where RTTI is not required, such as dynamic cast to an unambiguous base, and dynamic cast to (void *) . If you try to use dynamic_cast without --rtti in cases where RTTI is required, the compiler generates an error.


2 Answers

The functionality of the dynamic_cast goes far beyond a simple type check. If it was just a type check, it would be very easy to implement (something like what you have in your original post).

In addition to type checking, dynamic_cast can perform casts to void * and hierarchical cross-casts. These kinds of casts conceptually require some ability to traverse class hierarchy in both directions (up and down). The data structures needed to support such casts are more complicated than a mere scalar type id. The information the dynamic_cast is using is a part of RTTI.

Trying to describe it here would be counterproductive. I used to have a good link that described one possible implementation of RTTI... will try to find it.

like image 97
AnT Avatar answered Oct 20 '22 22:10

AnT


I don't know the exact implementation, but here is an idea how I would do it:

Casting from Derived* to Base* can be done in compile time. Casting between two unrelated polimorphic types can be done in compile time too (just return NULL).

Casting from Base* to Derived* needs to be done in run-time, because multiple derived classes possible. The identification of dynamic type can be done using the virtual method table bound to the object (that's why it requires polymorphic classes).

This VMT probably contains extra information about the base classes and their data offsets. These data offsets are relevant when multiple inheritance is involved and is added to the source pointer to make it point to the right location.

If the desired type was not found among the base classes, dynamic_cast would return null.

like image 23
Calmarius Avatar answered Oct 20 '22 22:10

Calmarius