Dynamic _Cast in C++ - GeeksforGeeks

13 May, 2021
C++ is a powerful language. In C++ we can write a structured program and object-oriented program also. In this article, we will focus on dynamic_cast in C++. Now before start dynamic_cast in C++, first understand what is type casting in C++.’
Casting is a technique by which one data type to another data type. The operator used for this purpose is known as the cast operator. It is a unary operator which forces one data type to be converted into another data type. It takes on the format:
Syntax:
(Cast type) expression;              orCast type (expression)
Program 1:
C++
// C++ program to demonstrate the use// of typecasting#include <iostream>using namespace std;  // Driver Codeint main(){    // Variable declaration    int a, b;    float c;      a = 20;    b = 40;      // Typecasting    c = (float)a * b;      cout << "Result: " << c;      return 0;}
Result: 800

Explanation: In the above example first, the variable a is converted to float then multiplied by b, now the result is also floating float then the result is assigned to the variable c. Now, the value of c is 800. 
Program 2:
C++
// C++ program to read the values of two// variables and stored the result in// third one#include <iostream>using namespace std;  int main(){    // Variable declaration and    // initialization    int a = 7, b = 2;    float c;    c = a / b;      cout << "Result:" << c;      return 0;}
Result:3

Explanation: In the above case, the variable c is 3, not 3.5, because variables a and b both are integer types therefore a/b is also an integer type. After calculating a/b that is int type is assigned to the variable c which is float type. But a/b is int type i.e., 7/2 is 3, not 3.5. Therefore, the value of variable c is 3.
Program 3:
C++
// C++ program to read two variable value// (a, b) and perform typecasting#include <iostream>using namespace std;  // Driver Codeint main(){    // Variable declaration and    // initialization    int a = 7, b = 2;    float c;      // Type Casting    c = (float)a / b;    cout << "Result :" << c;      return 0;}
Result :3.5

Explanation: Now, the variable c is 3.5, because in the above expression first a is converted into float therefore a/b is also float type. 7.0/2 is 3.5. Then that is assigned to the variable c.
C++ supports four types of casting:
1.Static Cast2. Dynamic Cast3. Const Cast4. Reinterpret Cast
Static Cast: This is the simplest type of cast that can be used. It is a compile-time cast. It does things like implicit conversions between types (such as int to float, or pointer to void*), and it can also call explicit conversion functions (or implicit ones).
Dynamic Cast: A cast is an operator that converts data from one type to another type. In C++, dynamic casting is mainly used for safe downcasting at run time. To work on dynamic_cast there must be one virtual function in the base class. A dynamic_cast works only polymorphic base class because it uses this information to decide safe downcasting.
Syntax:
dynamic_cast <new_type>(Expression)
Downcasting: Casting a base class pointer (or reference) to a derived class pointer (or reference) is known as downcasting. In figure 1  casting from the Base class pointer/reference to the “derived class 1” pointer/reference showing downcasting (Base ->Derived class).
Upcasting: Casting a derived class pointer (or reference) to a base class pointer (or reference) is known as upcasting. In figure 1 Casting from Derived class 2 pointer/reference to the “Base class” pointer/reference showing Upcasting (Derived class 2 -> Base Class).
As we mention above for dynamic casting there must be one Virtual function. Suppose If we do not use the virtual function, then what is the result?
In that case, it generates an error message “Source type is not polymorphic”.
C++
// C++ program demonstrate if there// is no virtual function used in// the Base class#include <iostream>using namespace std;  // Base class declarationclass Base {    void print()    {        cout << "Base" << endl;    }};  // Derived Class 1 declarationclass Derived1 : public Base {    void print()    {        cout << "Derived1" << endl;    }};  // Derived class 2 declarationclass Derived2 : public Base {    void print()    {        cout << "Derived2" << endl;    }};  // Driver Codeint main(){    Derived1 d1;      // Base class pointer hold Derived1    // class object    Base* bp = dynamic_cast<Base*>(&d1);      // Dynamic casting    Derived2* dp2 = dynamic_cast<Derived2*>(bp);    if (dp2 == nullptr)        cout << "null" << endl;      return 0;}
not null

Virtual functions include run-time type information and there is no virtual function in the base class. So this code generates an error.
Case 1: Let’s take an example of dynamic_cast which demonstrates if the casting is successful, it returns a value of type new_type.
C++
// C++ Program demonstrates successful// dynamic casting and it returns a// value of type new_type#include <iostream>  using namespace std;// Base Class declarationclass Base {    virtual void print()    {        cout << "Base" << endl;    }};  // Derived1 class declarationclass Derived1 : public Base {    void print()    {        cout << "Derived1" << endl;    }};  // Derived2 class declarationclass Derived2 : public Base {    void print()    {        cout << "Derived2" << endl;    }};  // Driver Codeint main(){    Derived1 d1;      // Base class pointer holding    // Derived1 Class object    Base* bp = dynamic_cast<Base*>(&d1);      // Dynamic_casting    Derived1* dp2 = dynamic_cast<Derived1*>(bp);    if (dp2 == nullptr)        cout << "null" << endl;    else        cout << "not null" << endl;      return 0;}
not null

Explanation: In this program, there is one base class and two derived classes (Derived1, Derived2), here the base class pointer hold derived class 1 object (d1). At the time of dynamic_casting base class, the pointer held the Derived1 object and assigning it to derived class 1, assigned valid dynamic_casting. 
Case 2: Now, If the cast fails and new_type is a pointer type, it returns a null pointer of that type.
C++
// C++ Program demonstrate if the cast// fails and new_type is a pointer type// it returns a null pointer of that type#include <iostream>using namespace std;  // Base class declarationclass Base {    virtual void print()    {        cout << "Base" << endl;    }};  // Derived1 class declarationclass Derived1 : public Base {    void print()    {        cout << "Derived1" << endl;    }};  // Derived2 class declarationclass Derived2 : public Base {    void print()    {        cout << "Derived2" << endl;    }};  // Driver Codeint main(){    Derived1 d1;    Base* bp = dynamic_cast<Base*>(&d1);      // Dynamic Casting    Derived2* dp2 = dynamic_cast<Derived2*>(bp);    if (dp2 == nullptr)        cout << "null" << endl;      return 0;}
null

Explanation: In this program, at the time of dynamic_casting base class pointer holding the Derived1 object and assigning it to derived class 2, which is not valid dynamic_casting. So, it returns a null pointer of that type in the result.
Case 3:Now take one more case of dynamic_cast, If the cast fails and new_type is a reference type, it throws an exception that matches a handler of type std::bad_cast and gives a warning: dynamic_cast of “Derived d1” to “class  Derived2&” can never succeed. 
C++
// C++ Program demonstrate if the cast// fails and new_type is a reference// type it throws an exception#include <exception>#include <iostream>using namespace std;  // Base class declarationclass Base {    virtual void print()    {        cout << "Base" << endl;    }};  // Derived1 classclass Derived1 : public Base {    void print()    {        cout << "Derived1" << endl;    }};  // Derived2 classclass Derived2 : public Base {    void print()    {        cout << "Derived2" << endl;    }};  // Driver Codeint main(){    Derived1 d1;    Base* bp = dynamic_cast<Base*>(&d1);      // Type casting    Derived1* dp2 = dynamic_cast<Derived1*>(bp);    if (dp2 == nullptr)        cout << "null" << endl;    else        cout << "not null" << endl;      // Exception handling block    try {        Derived2& r1 = dynamic_cast<Derived2&>(d1);    }    catch (std::exception& e) {        cout << e.what() << endl;    }      return 0;}
Output:
warning: dynamic_cast of ‘Derived1 d1’ to ‘class Derived2&’ can never succeed Derived2& r1 = dynamic_cast<Derived2&>(d1);
Note:
A Dynamic_cast has runtime overhead because it checks object types at run time using “Run-Time Type Information“.
If there is a surety we will never cast to wrong object then always avoid dynamic_cast and use static_cast.  
CPP-Basics
Data Type
C++
C++ Programs
Data Type
CPP
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Operator Overloading in C++
Iterators in C++ STL
Friend class and function in C++
Polymorphism in C++
Sorting a vector in C++
Header files in C/C++ and its uses
C++ Program for QuickSort
How to return multiple values from a function in C or C++?
CSV file management using C++
Program to print ASCII Value of a character