Open In App

static_cast in C++

Improve
Improve
Like Article
Like
Save
Share
Report

A Cast operator is a unary operator which forces one data type to be converted into another data type.

C++ supports 4 types of casting:

  1. Static Cast
  2. Dynamic Cast
  3. Const Cast
  4. Reinterpret Cast

This article focuses on discussing the static_cast in detail.

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.

Syntax of static_cast

static_cast <dest_type> (source);

The return value of static_cast will be of dest_type.

Example of static_cast

Below is the C++ program to implement static_cast:

C++




// C++ Program to demonstrate
// static_cast
#include <iostream>
using namespace std;
 
// Driver code
int main()
{
    float f = 3.5;
 
    // Implicit type case
    // float to int
    int a = f;
    cout << "The Value of a: " << a;
 
    // using static_cast for float to int
    int b = static_cast<int>(f);
    cout << "\nThe Value of b: " << b;
}


Output

The Value of a: 3
The Value of b: 3

The behavior of static_cast for Different Scenarios

1. static_cast for primitive data type pointers:

Now let’s make a few changes to the above code.

C++




// C++ Program to demonstrate
// static_cast char* to int*
#include <iostream>
using namespace std;
 
// Driver code
int main()
{
  int a = 10;
  char c = 'a';
   
  // Pass at compile time,
  // may fail at run time
  int* q = (int*)&c;
  int* p = static_cast<int*>(&c);
  return 0;
}


Output

error: invalid 'static_cast' from type 'int*' to type 'char*'

Explanation: This means that even if you think you can somehow typecast a particular object pointer into another but it’s illegal, the static_cast will not allow you to do this.

2. Converting an Object using a User-Defined Conversion Operator

static_cast is able to call the conversion operator of the class if it is defined. Let’s take another example of converting an object to and from a class.

Example:

C++




// C++ Program to cast
// class object to string
// object
#include <iostream>
#include <string>
using namespace std;
 
// new class
class integer {
    int x;
 
public:
    // constructor
    integer(int x_in = 0)
        : x{ x_in }
    {
        cout << "Constructor Called" << endl;
    }
 
    // user defined conversion operator to string type
    operator string()
    {
        cout << "Conversion Operator Called" << endl;
        return to_string(x);
    }
};
 
// Driver code
int main()
{
    integer obj(3);
    string str = obj;
    obj = 20;
 
    // using static_cast for typecasting
    string str2 = static_cast<string>(obj);
    obj = static_cast<integer>(30);
 
    return 0;
}


Output

Constructor Called
Conversion Operator Called
Constructor Called
Conversion Operator Called
Constructor Called

Explanation: Lets the try to understand the above output line by line:

  1. When obj is created then the constructor is called which in our case is also a Conversion Constructor (for C++14 rules are changed a bit).
  2. When you create str out of obj, the compiler will not throw an error as we have defined the Conversion operator.
  3. When you make obj = 20, you are actually calling the conversion constructor.
  4. When you make str2 out of static_cast, it is pretty similar to string str = obj; but with tight type checking.
  5. When you write obj = static_cast <integer> (30), you convert 30 into an integer using static_cast.

3. static_cast for Inheritance in C++

static_cast can provide both upcasting and downcasting in case of inheritance. The following example demonstrates the use of static_cast in the case of upcasting.

Example:

C++




// C++ Program to demonstrate
// static_cast in inheritance
#include <iostream>
using namespace std;
class Base
{};
class Derived : public Base
{};
 
// Driver code
int main()
{
  Derived d1;
   
  // Implicit cast allowed
  Base* b1 = (Base*)(&d1);
   
  // upcasting using static_cast
  Base* b2 = static_cast<Base*>(&d1);
  return 0;
}


Explanation: The above code will compile without any error.

  1. We took the address of d1 and explicitly cast it into Base and stored it in b1.
  2. We took the address of d1 and used static_cast to cast it into Base and stored it in b2.

In the above example, we inherited the base class as public. What happens when we inherit it as private? The below example demonstrate the following:

Example:

C++




// C++ program to demonstrate
// static_cast in case of
// private inheritance
#include <iostream>
using namespace std;
 
class Base
{};
 
class Derived: private Base
{
  // Inherited private/protected
  // not public
};
 
// Driver code
int main()
{   
  Derived d1;
   
  // Implicit type cast allowed
  Base* b1 = (Base*)(&d1);
   
  // static_cast not allowed
  Base* b2 = static_cast<Base*>(&d1);
  return 0;
}


Compile-time Error:

[Error] 'Base' is an inaccessible base of 'Derived'

Explanation: The above code will not compile even if you inherit it as protected.

So to use static_cast in case of inheritance, the base class must be accessible, non virtual and unambiguous.

4. static_cast to Cast ‘to and from’ Void Pointer

static_cast operator allows casting from any pointer type to void pointer and vice versa.

Example:

C++




// C++ program to demonstrate
// static_cast to cast 'to and
// from' the void pointer
#include <iostream>
using namespace std;
 
// Driver code
int main()
{
  int i = 10;
  void* v = static_cast<void*>(&i);
  int* ip = static_cast<int*>(v);
  cout << *ip;
  return 0;
}


Output

10


Last Updated : 13 Jul, 2023
Like Article
Save Article
Previous
Next
Share your thoughts in the comments