How to Use Dynamic Cast in C++

This article will demonstrate multiple methods about how to use dynamic cast in C++.

Use dynamic_cast to Convert From Base Class Pointer to Derived One

dynamic_cast allows the programmer to convert pointers and references to classes across the inheritance hierarchy. As an example, the base class pointer can be cast into a derived class pointer and allow the programmer to call derived class member functions.

dynamic_cast is part of the Run-Time Type Information (RTTI) feature that provides a way to access the type of an object at run time instead of compile time.

Mind that dynamic_cast can not be used to convert between the primitive types like int or float. Additionally, one should only use dynamic_cast when the base class contains at least one virtual member function. In the following example, we declare a new Base class pointer and cast it into the new pointer to the Derived class. Since dynamic_cast returns a null pointer, if the cast is unsuccessful, we can put the expression in the if statement as a condition.

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {
    virtual ~Base() = default;
};

struct Derived: public Base { };

int main()
{
    Base *bp = new Derived;
    if (Derived *dp = dynamic_cast<Derived*>(bp))
    {
        cout << "Successful cast - can use the pointer to 'Derived' object dp" << endl;
    }

    delete bp;
    return EXIT_SUCCESS;
}

Output:

Successful cast - can use the pointer to 'Derived' object dp

The programmer can safely access the object in the if section scope and call Derived class member methods as needed. Note though, that since we are casting Derived class type to Base, on the 13th line, we specify Derived after new operator as the following code would yield unsuccessful cast:

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {
    virtual ~Base() = default;
};

struct Derived: public Base { };

int main()
{
    Base *bp = new Base;
    if (Derived *dp = dynamic_cast<Derived*>(bp))
    {
        cout << "Successful cast - can use the pointer to 'Derived' object dp" << endl;
    }

    delete bp;
    return EXIT_SUCCESS;
}

The other part of the RTTI feature is the typeid operator, which returns the type of the given expression. It can be utilized to compare types of multiple expressions, as demonstrated in the next code sample. Note that, <typeinfo> header must be included when using the typeid operator.

#include <iostream>
#include <typeinfo>

using std::cout;
using std::endl;

struct Base {
    virtual ~Base() = default;
};

struct Derived: public Base { };

int main()
{
    Base *bp = new Derived;
    if (Derived *dp = dynamic_cast<Derived*>(bp))
    {
        cout << "Successful cast - can use the pointer to 'Derived' object dp" << endl;
        if (typeid(*bp) == typeid(*dp)) {
            cout << "bp and dp are of same type" << endl;
        }
    }

    delete bp;
    return EXIT_SUCCESS;
}

Output:

Successful cast - can use the pointer to 'Derived' object dp
bp and dp are of same type