The dynamic_cast operator performs type conversions at run time. The dynamic_cast operator guarantees the conversion of a pointer to a base class to a pointer to a derived class, or the conversion of an lvalue referring to a base class to a reference to a derived class. A program can thereby use a class hierarchy safely. This operator and the typeid operator provide runtime type information (RTTI) support in C++.
The expression dynamic_cast<T>(v) converts the expression v to type T. Type T must be a pointer or reference to a complete class type or a pointer to void. If T is a pointer and the dynamic_cast operator fails, the operator returns a null pointer of type T. If T is a reference and the dynamic_cast operator fails, the operator throws the exception std::bad_cast. You can find this class in the standard library header <typeinfo>.
The dynamic_cast operator requires runtime type information (RTTI) to be generated, which must be explicitly specified at compile time through a compiler option.
If T is a void pointer, then dynamic_cast will return the starting address of the object pointed to by v. The following example demonstrates this:
#include <iostream> using namespace std; struct A { virtual ~A() { }; }; struct B : A { }; int main() { B bobj; A* ap = &bobj; void * vp = dynamic_cast<void *>(ap); cout << "Address of vp : " << vp << endl; cout << "Address of bobj: " << &bobj << endl; }
The output of this example will be similar to the following. Both vp and &bobj will refer to the same address:
Address of vp : 12FF6C Address of bobj: 12FF6C
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 pointer or reference to a class B, where class A is a base class of B. The problem with downcasts is that a pointer of type A* can and must point to any object of a class that has been derived from A. The dynamic_cast operator ensures that if you convert a pointer of class A to a pointer of a class B, the object that A points to belongs to class B or a class derived from B.
The following example demonstrates the use of the dynamic_cast operator:
#include <iostream> using namespace std; struct A { virtual void f() { cout << "Class A" << endl; } }; struct B : A { virtual void f() { cout << "Class B" << endl; } }; struct C : A { virtual void f() { cout << "Class C" << endl; } }; void f(A* arg) { B* bp = dynamic_cast<B*>(arg); C* cp = dynamic_cast<C*>(arg); if (bp) bp->f(); else if (cp) cp->f(); else arg->f(); }; int main() { A aobj; C cobj; A* ap = &cobj; A* ap2 = &aobj; f(ap); f(ap2); }
The following is the output of the above example:
Class C Class A
The function f() determines whether the pointer arg points to an object of type A, B, or C. The function does this by trying to convert arg to a pointer of type B, then to a pointer of type C, with the dynamic_cast operator. If the dynamic_cast operator succeeds, it returns a pointer that points to the object denoted by arg. If dynamic_cast fails, it returns 0.
You may perform downcasts with the dynamic_cast operator only on polymorphic classes. In the above example, all the classes are polymorphic because class A has a virtual function. The dynamic_cast operator uses the runtime type information generated from polymorphic classes.
Related information