C++

Static_Cast vs Dynamic_Cast in C++

Converting a value from a certain type of data into another is referred to as type casting or type conversion. It allows you to change the interpretation and representation of a value to make it compatible with a different data type.

Type casting can be broadly categorized into two types: implicit casting and explicit casting. When a value needs to be converted from one type to another, explicit casting is done by the programmer that utilizes the casting operators. In C++, there are several casting operators available for explicit casting: static_cast, dynamic_cast, reinterpret_cast, and const_cast.

This post only covers about the “static_cast” and “dynamic_cast”.

Static Casting in C++

An explicit type conversion between two types that are compatible is carried out by the casting operator which is known as “static_cast” in C++. It is a compile-time conversion that allows you to convert a value of one type to another, provided that the conversion is defined and considered safe by the language.

The syntax for “static_cast” is as follows:

static_cast<new_type>(expression)

Here, the “new_type” represents the desired type to which you want to convert the expression. A variable, a constant, or any valid C++ expression can be utilized as the expression.

There are numerous conversion types that the “static_cast” can be utilized for. It can convert between different numeric types, such as converting an int to a double or a float to an int, as long as the conversion is well-defined. It allows you to convert the pointers or references between the related types in a hierarchy, such as the base class pointers, to the derived class pointers or vice versa. Many other operations can be done using it.

It’s important to note that “static_cast” performs only a limited set of conversions and is intended for safe and well-defined conversions. For more specialized conversions or type manipulations, C++ provides other casting operators like dynamic_cast.

Let’s see a practical implementation of “static_cast” in the C++ program.

Converting Float to Int

The first program converts a float value to an int value using static casting.

#include <iostream>

using namespace std;

int main()

{

  float val = 14.2;

 

  int Y = static_cast<int>(val);

  cout << "\nThe Value of Y is: " << Y;

}

The header files are initially included in the program. The driver code starts as we invoke the main() function. We initialize a float variable “val” to a value of “14.2”.

Now, we convert this float value to “int” data type by utilizing the “static_cast”. A “Y” variable with “int” type is declared and assigned with the output from static_cast<int>. Here, “int” is the desired data type for conversion. Inside the round brackets, the variable that stores the value to be transformed is specified. So, the “static_cast” takes the value from the “val” variable, converts it into the desired type which is “int”, and stores it in the “Y” variable. Note that the value after point (.2) is lost as we are converting to “int” type. The “int” value that is stored in the “Y” variable is displayed by utilizing the “cout” statement.

Here is the output “int” value:

Converting the Int Pointer to Generic Type

We now use the “static_cast” to convert the “int” type pointer to a void* in a C++ program.

int main()

{

int* p1 = new int(5);

void* p2 = static_cast<void*>(p1);

}

In this example, “p1”, which is a pointer to int, is explicitly cast to a void* p2 using the “static_cast”. The pointer type is converted to a generic void* pointer which can store any kind of pointer.

Although the “static_cast” has numerous applications, we simply covered the fundamentals here.

Dynamic Casting in C++

Another casting operator in C++ that is mainly utilized for runtime type checking and type conversion within polymorphic class hierarchies is the “dynamic_cast”. It enables you to securely change the base class pointers or references into the derived class pointers or references, and vice versa.

The syntax for “dynamic_cast” is as follows:

dynamic_cast<new_type>(expression)

Here, the “new_type” represents the desired type to which you want to convert the expression. A polymorphic class can be referenced or pointed to in the expression.

The “dynamic_cast” checks if the object that is pointed to by the expression is a complete object of the target type. If the object doesn’t match the target type and the base class includes at least one virtual function, the “dynamic_cast” returns a null pointer. Furthermore, it verifies that the object expression refers to  a complete object of the desired type. If the object does not belong to the desired type and the base class contains at least one virtual function, the “dynamic_cast” throws the “std::bad_cast” exception.

It’s important to note that “dynamic_cast” is intended for use with polymorphic classes, i.e., classes that include a minimum of one virtual function. In the absence of any virtual functions in the base class, the “dynamic_cast” cannot be used for the type conversion. Also, “dynamic_cast” can be relatively slower compared to other casting operators due to the involved runtime type checking.

With the help of a C++ program, we will learn how to implement the “dynamic_cast” for conversion.

#include <iostream>

using namespace std;

class Base {

public:

  virtual ~Base() {}

};

class Derived_Class : public Base {

public:

  void derivedMethod() {

    cout << "Derived method is called!" << endl;

  }

};

int main() {

  Base* b = new Derived_Class;

  Derived_Class* d = dynamic_cast<Derived_Class*>(b);

  if (d != nullptr) {

    d->derivedMethod();

  } else {

    cout << "Dynamic casting got failed!" << endl;

  }

  delete b;

  return 0;

}

In this example, we have a base class called “Base” and a derived class which is termed as “Derived_Class”. The derived class has the derivedMethod() method which, when called, prints a “Derived method is called!” statement. Inside the main() function, we create a pointer “b” of type Base* that points to an object of “Derived_Class”.

Then, “b” is transformed into the Derived_Class* by utilizing the “dynamic_cast”. Since the object that is being pointed to is of “Derived_Class” type, the dynamic casting succeeds. The “d” pointer is not null, so we can safely call the derivedMethod() on it. The program outputs “Derived method is called!” which indicates that the derived method is successfully invoked.

If the dynamic cast fails, i.e., the object that is being pointed to is not of “Derived_Class” type, the dynamic_cast returns a null pointer. In that case, the program outputs the “Dynamic cast failed!” instead.

The generated output is given as follows:

Conclusion

This post focused on the two types of casting in C++ which are “static_cast” and “dynamic_cast”. We provided you with a complete overview of both types of casting. Also, the use of these type castings is elaborated on. We carried out the different examples for the “static_cast” as well as “dynamic_cast” to better comprehend the concepts. The outputs for the programs are also displayed.

About the author

Omar Farooq

Hello Readers, I am Omar and I have been writing technical articles from last decade. You can check out my writing pieces.