What's the difference between static_cast vs dynamic_cast in C++?

Overview

In C++, we can assign one variable to the other variable while both are of the same type, but what if both of the variables are of different types? For such cases, implicit type conversion is used, which means converting one data type to another. This is also known as typecasting. In C++, typecasting may or may not be implicitly supported. Let’s discuss two of these methods.

  • static_cast
  • dynamic_cast

static_cast

static_cast is used for ordinary typecasting. It is responsible for the implicit type of coercion and is also called explicitly. We should use it in cases like converting the int to float, int to char, etc.

Let’s discuss an example to see how it works.

#include<iostream>
using namespace std;
int main()
{
float i = 21.4;
int x , y;
x = i; //Type conversion from float to int
y = static_cast<int>(i);
cout<< x <<"\n" << y;
}

Explanation

  • Line 5: We initialize a float value.

  • Line 6: We initialize variables of integer type.

  • Line 7–9: We typecast a float value to an integer value and print it.

Lines 7 and 8 are doing the same work. The only difference is that if a program fails and we want to check where the implicit cast is used, searching line 7 in all the code is difficult. That’s why we use the static_cast in such cases, so that it can be figured out quickly.

dynamic_cast

In C++, we can treat the derived class’s reference or pointer as the base class’s pointer. This method is known as upcasting in C++. But its opposite process is known as downcasting, which is not allowed in C++. So, the dynamic_cast in C++ promotes safe downcasting. We can only perform this in polymorphic classes, which must have at least one virtual function.

Let’s discuss an example to see how it works.

#include<iostream>
using namespace std;
class parent
{
public:
virtual void vehicle()
{
cout<<"Parent";
}
};
class child : public parent
{
public:
void car()
{
cout<<"Child";
}
};
int main()
{
parent *p = new child;
child *c;
c = p; //base class pointer assigned to the derived class pointer
c->car();
}

This code will produce an error as we’re downcasting, and as we’re trying to assign the pointer of the base class to the derived class. To ensure the downcasting, we need to rewrite the code again with the help of dynamic_cast.

#include<iostream>
using namespace std;
class parent
{
public:
virtual void vehicle()
{
cout<<"Parent";
}
};
class child : public parent
{
public:
void car()
{
cout<<"Child";
}
};
int main()
{
parent *p = new child;
child *c;
c = dynamic_cast<child*>(p); //to promote downcasting
cout<< c <<"\n";
c->car();
}

Explanation

  • Line 3-10: We make a class Parent with a virtual function named as Vehicle.

  • Line 11-18: We make a class Child with a function named Car.

  • Line 19-26: We make the pointers of parent and child classes and then call the dynamic_cast downcast. We then print the memory, which points to the child class, and then call the function of the child class.

Free Resources