C++ dynamic_cast Keyword

The dynamic_cast keyword in C++ is used to safely convert pointers or references between classes in an inheritance hierarchy. It ensures that the conversion is valid and returns a nullptr (for pointers) or throws a std::bad_cast exception (for references) if the conversion is invalid. This makes dynamic_cast particularly useful in polymorphic programming.

The dynamic_cast operator works only with classes that have at least one virtual function, typically a virtual destructor, to enable runtime type information (RTTI).


Syntax

</>
Copy
dynamic_cast(expression);
target_type
The type to which the pointer or reference is being cast.
expression
The pointer or reference being cast.

Examples

Example 1: Upcasting and Downcasting with Pointers

This example demonstrates how to use dynamic_cast for safe downcasting between base and derived class pointers.

</>
Copy
#include <iostream>
using namespace std;

class Base {
public:
    virtual void show() { cout << "Base class" << endl; }
};

class Derived : public Base {
public:
    void show() override { cout << "Derived class" << endl; }
};

int main() {
    Base* basePtr = new Derived(); // Upcasting: Derived to Base
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // Downcasting: Base to Derived

    if (derivedPtr) {
        derivedPtr->show(); // Safe to call Derived class method
    } else {
        cout << "Downcasting failed!" << endl;
    }

    delete basePtr;
    return 0;
}

Output:

Derived class

Explanation:

  1. A Base* pointer is assigned a Derived object (upcasting).
  2. dynamic_cast is used to safely downcast the Base* back to a Derived*.
  3. The check if (derivedPtr) ensures the downcasting was successful.
  4. The Derived class method is safely invoked using the downcast pointer.

Example 2: Invalid Downcasting

This example demonstrates what happens when a dynamic_cast fails.

</>
Copy
#include <iostream>
using namespace std;

class Base {
public:
    virtual void show() { cout << "Base class" << endl; }
};

class Derived : public Base {
public:
    void show() override { cout << "Derived class" << endl; }
};

class AnotherDerived : public Base {};

int main() {
    Base* basePtr = new AnotherDerived(); // Base pointer to AnotherDerived object
    Derived* derivedPtr = dynamic_cast<Derived*>(basePtr); // Attempt downcasting

    if (derivedPtr) {
        derivedPtr->show();
    } else {
        cout << "Downcasting failed!" << endl;
    }

    delete basePtr;
    return 0;
}

Output:

Downcasting failed!

Explanation:

  1. The Base* pointer points to an AnotherDerived object.
  2. The dynamic_cast attempts to downcast the pointer to a Derived*.
  3. Since the object is not of type Derived, the dynamic_cast returns nullptr.
  4. The program checks if the cast succeeded and prints “Downcasting failed!” when it does not.

Key Points about dynamic_cast Keyword

  1. The dynamic_cast operator is used for safe type casting in an inheritance hierarchy.
  2. It requires the presence of at least one virtual function (typically a virtual destructor) in the base class to enable RTTI (Run-Time Type Information).
  3. When downcasting pointers, dynamic_cast returns nullptr if the cast fails.
  4. When downcasting references, dynamic_cast throws a std::bad_cast exception if the cast fails.
  5. It is safer than static_cast, as it performs runtime checks to ensure the validity of the cast.