Dynamic _Cast in C++

Last Updated : 11 Jun, 2026

dynamic_cast is a runtime type conversion operator used in polymorphic inheritance hierarchies. It performs runtime type checking to ensure that a conversion is valid before it is applied.

  • Commonly used for downcasting from a base class to a derived class.
  • Requires the base class to have at least one virtual function.
  • Indicates failed conversions through nullptr (for pointers) or std::bad_cast (for references).
C++
#include <iostream>
using namespace std;

class Base{
public:

    // Required for dynamic_cast
    virtual void show() { }
};

class Derived : public Base {
public:
    void display() {
        cout << "Dynamic Cast Successful";
    }
};

int main() {
    Base* ptr = new Derived();

    Derived* dptr = dynamic_cast<Derived*>(ptr);

    if (dptr)
        dptr->display();

    delete ptr;
    return 0;
}

Output
Dynamic Cast Successful

Explanation: dynamic_cast safely converts a base class pointer to a derived class pointer at runtime. If the conversion is valid, it returns the converted pointer; otherwise, it returns nullptr

Syntax

dynamic_cast<new_type>(expression)

Parameters

  • new_type: Target type for the conversion.
  • expression: Pointer or reference being converted.

Return Value

  • Returns a valid pointer if the cast succeeds.
  • Returns nullptr if a pointer cast fails.
  • Throws std::bad_cast if a reference cast fails.

Note: dynamic_cast relies on Run-Time Type Information (RTTI), which introduces some runtime overhead. If a conversion is guaranteed to be valid, static_cast is generally more efficient. 

Downcasting Using dynamic_cast

dynamic_cast is commonly used to safely convert a base class pointer to a derived class pointer.

C++
#include <iostream>
using namespace std;

// Base Class declaration
class Base {
public:
    virtual void print() {
        cout << "Base" << endl;
    }
};

// Derived1 class declaration
class Derived1 : public Base {
public:
    void print() {
        cout << "Derived1" << endl;
    }
};

int main() {
    Derived1 d1;

    // Base class pointer holding
    // Derived1 Class object
    Base* bp = &d1;

    // Dynamic_casting
    Derived1* dp2 = dynamic_cast<Derived1*>(bp);
    if (dp2 == nullptr)
        cout << "Casting Failed" << endl;
    else
        cout << "Casting Successful" << endl;

    return 0;
}

Output
Casting Successful

Explanation:

  • bp is a base class pointer pointing to a Derived1 object.
  • dynamic_cast checks the actual object type at runtime.
  • Since the object is of type Derived1, the cast succeeds.
  • A valid Derived1* pointer is returned.

Requirement for dynamic_cast

For downcasting to work, the base class must be polymorphic. A class becomes polymorphic when it contains at least one virtual function.

Example: Non-Polymorphic Base Class

C++
#include <iostream>
using namespace std;

// Non-polymorphic base class
class Base {
public:
    void print() {
        cout << "Base" << endl;
    }
};

class Derived1 : public Base {
public:
    void print() {
        cout << "Derived1" << endl;
    }
};

int main() {
    Derived1 d1;
    Base* bp = &d1;

    // Dynamic_casting
    Derived1* dp2 = dynamic_cast<Derived1*>(bp);
    if (dp2 == nullptr)
        cout << "Casting Failed" << endl;
    else
        cout << "Casting Successful" << endl;

    return 0;
}


Output

main.cpp: In function ‘int main()’:
main.cpp:24:21: error: cannot ‘dynamic_cast’ ‘bp’ (of type ‘class Base*’) to type ‘class Derived1*’ (source type is not polymorphic)
24 | Derived1* dp2 = dynamic_cast<Derived1*>(bp);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~

Explanation

  • The base class does not contain any virtual function.
  • Therefore, it is not polymorphic.
  • RTTI information is unavailable.
  • As a result, dynamic_cast cannot perform runtime type checking and compilation fails.

Invalid Downcasting

A cast fails when the actual object type does not match the target type.

C++
#include <iostream>
using namespace std;

class Base {
    virtual void print() {
        cout << "Base" << endl;
    }
};

// Derived1 class declaration
class Derived1 : public Base {
    void print() {
        cout << "Derived1" << endl;
    }
};

// Derived2 class declaration
class Derived2 : public Base {
    void print() {
        cout << "Derived2" << endl;
    }
};

int main() {
    Derived1 d1;
    Base* bp = &d1;

    // Dynamic Casting
    Derived2* dp2 = dynamic_cast<Derived2*>(bp);
    if (dp2 == nullptr)
        cout << "Casting Failed" << endl;
    else
        cout << "Casting Successful" << endl;

    return 0;
}

Output
Casting Failed

Explanation

  • bp points to a Derived1 object.
  • The code attempts to convert it to Derived2*.
  • Since the object is not of type Derived2, the conversion is invalid.
  • dynamic_cast returns nullptr.

Downcasting References

When casting references, a failed conversion results in an exception instead of returning nullptr.

C++
#include <exception>
#include <iostream>
using namespace std;

class Base {
    virtual void print() {
        cout << "Base" << endl;
    }
};

class Derived1 : public Base {
    void print() {
        cout << "Derived1" << endl;
    }
};

class Derived2 : public Base {
    void print() {
        cout << "Derived2" << endl;
    }
};

int main() {
    Derived1 d1;
    Base* bp = dynamic_cast<Base*>(&d1);

    // Type casting
    Derived1* dp2 = dynamic_cast<Derived1*>(bp);

    // Exception handling block
    try {
        Derived2& r1 = dynamic_cast<Derived2&>(d1);
    }
    catch (std::exception& e) {
        cout << e.what() << endl;
    }

    return 0;
}

Output

main.cpp:31:15: warning: unused variable ‘dp2’ [-Wunused-variable]
31 | Derived1* dp2 = dynamic_cast<Derived1*>(bp);
| ^~~
std::bad_cast

Explanation

  • d1 is an object of type Derived1.
  • The code attempts to convert it to a Derived2 reference.
  • The conversion is invalid because the object is not a Derived2.
  • Since references cannot be nullptr, dynamic_cast throws a std::bad_cast exception.
Comment