Skip to content
Related Articles

Related Articles

Improve Article
Dynamic _Cast in C++
  • Difficulty Level : Easy
  • Last Updated : 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++.’

Type Casting:

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;
              or
Cast type (expression)

Program 1:



C++




// C++ program to demonstrate the use
// of typecasting
#include <iostream>
using namespace std;
  
// Driver Code
int main()
{
    // Variable declaration
    int a, b;
    float c;
  
    a = 20;
    b = 40;
  
    // Typecasting
    c = (float)a * b;
  
    cout << "Result: " << c;
  
    return 0;
}
Output:
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;
}
Output:
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 Code
int main()
{
    // Variable declaration and
    // initialization
    int a = 7, b = 2;
    float c;
  
    // Type Casting
    c = (float)a / b;
    cout << "Result :" << c;
  
    return 0;
}
Output:
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 Cast
2. Dynamic Cast
3. Const Cast
4. 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 declaration
class Base {
    void print()
    {
        cout << "Base" << endl;
    }
};
  
// Derived Class 1 declaration
class Derived1 : public Base {
    void print()
    {
        cout << "Derived1" << endl;
    }
};
  
// Derived class 2 declaration
class Derived2 : public Base {
    void print()
    {
        cout << "Derived2" << endl;
    }
};
  
// Driver Code
int 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;
}
Output:
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 declaration
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;
    }
};
  
// Driver Code
int 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;
}
Output:
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 declaration
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;
    }
};
  
// Driver Code
int 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;
}
Output:
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 declaration
class Base {
    virtual void print()
    {
        cout << "Base" << endl;
    }
};
  
// Derived1 class
class Derived1 : public Base {
    void print()
    {
        cout << "Derived1" << endl;
    }
};
  
// Derived2 class
class Derived2 : public Base {
    void print()
    {
        cout << "Derived2" << endl;
    }
};
  
// Driver Code
int 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. 
     
Want to learn from the best curated videos and practice problems, check out the C++ Foundation Course for Basic to Advanced C++ and C++ STL Course for the language and STL. To complete your preparation from learning a language to DS Algo and many more, please refer Complete Interview Preparation Course.
My Personal Notes arrow_drop_up
Recommended Articles
Page :