Skip to main content

RTTI with dynamic_cast and typeid

Short answer

RTTI identifies the actual type of a polymorphic object at run time using typeid (compares types, gets name) and dynamic_cast (safe downcast, returns null on failure). They work only with classes having virtual functions, enabling type-specific operations safely.

What do you mean by run-time type information (RTTI)? Explain how dynamic cast and typeid operators are used to achieve RTTI with suitable example.

Run-time type information (RTTI) is a C++ mechanism that lets a program find the actual type of an object at run time, when only a base class pointer or reference is available. It works only with polymorphic classes, i.e. classes having at least one virtual function. The two main operators are typeid and dynamic_cast.

typeid operator

Returns a type_info object describing the type of an expression. Its name() gives the type name, and objects can be compared with == / !=. Header: <typeinfo>.

typeid(*ptr).name();
typeid(*p1) == typeid(Derived)

dynamic_cast operator

Safely converts a base pointer/reference to a derived pointer/reference at run time. The cast succeeds only if the object really is of that derived type. For pointers it returns NULL (nullptr) on failure; for references it throws bad_cast.

Derived *d = dynamic_cast<Derived*>(basePtr);

Example

#include <iostream>
#include <typeinfo>
using namespace std;

class Animal {
public:
    virtual void speak() { cout << "Animal sound" << endl; }
    virtual ~Animal() {}
};
class Dog : public Animal {
public:
    void speak() { cout << "Bark" << endl; }
    void fetch() { cout << "Dog fetches ball" << endl; }
};
class Cat : public Animal {
public:
    void speak() { cout << "Meow" << endl; }
};

void check(Animal *a) {
    cout << "Type: " << typeid(*a).name() << endl;
    Dog *d = dynamic_cast<Dog*>(a);      // succeeds only for Dog
    if (d) d->fetch();
    else   cout << "Not a Dog" << endl;
}

int main() {
    Animal *p1 = new Dog;
    Animal *p2 = new Cat;
    check(p1);
    check(p2);
    if (typeid(*p1) == typeid(Dog)) cout << "p1 is a Dog" << endl;
    delete p1;
    delete p2;
    return 0;
}

Output (type names vary by compiler; GCC shows mangled names like 3Dog):

Type: 3Dog
Dog fetches ball
Type: 3Cat
Not a Dog
p1 is a Dog

dynamic_cast lets us call fetch(), which exists only in Dog, safely through an Animal*. If the pointer actually points to a Cat, the cast returns null instead of causing undefined behaviour.

✓ Answer checked by Claude Opus 5.5 (high effort)

All Object Oriented Programming chapter 7 questions →