Open In App

Casting Operators in C++

Last Updated : 12 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Casting operators are used for type casting in C++. They are used to convert one data type to another. C++ supports four types of casts:

  1. static_cast
  2. dynamic_cast
  3. const_cast
  4. reinterpret_cast

1. static_cast

The static_cast operator is the most commonly used casting operator in C++. It performs compile-time type conversion and is mainly used for explicit conversions that are considered safe by the compiler. 

Syntax of static_cast

static_cast <new_type> (expression);

where,

  • expression: Data to be converted.
  • new_type: Desired type of expression

The static_cast can be used to convert between related types, such as numeric types or pointers in the same inheritance hierarchy.

Example of static_cast

C++
// C++ program to illustrate the static_cast
#include <iostream>
#include <typeinfo>
using namespace std;

int main()
{

    int num = 10;

    // converting int to double
    double numDouble = static_cast<double>(num);

    // printing data type
    cout << typeid(num).name() << endl;

    // typecasting
    cout << typeid(static_cast<double>(num)).name() << endl;

    // printing double type t
    cout << typeid(numDouble).name() << endl;

    return 0;
}

Output
i
d
d

In this example, we have included the “typeinfo” library so that we can use typeid() function to check the data type. We have defined an integer variable ‘num’ and converted it into a double using static_cast. After that, we print the data types of variables and pass static_cast<double>(num) in typeid() function to check its data type. we can see the output “i, d, d” is printed where ‘i’ denotes integer and ‘d’ denotes double.

2. dynamic_cast

The dynamic_cast operator is mainly used to perform downcasting (converting a pointer/reference of a base class to a derived class). It ensures type safety by performing a runtime check to verify the validity of the conversion.

Syntax of dynamic_cast

dynamic_cast <new_type> (expression);

If the conversion is not possible, dynamic_cast returns a null pointer (for pointer conversions) or throws a bad_cast exception (for reference conversions).

Example of dynamic_cast

C++
// C++ program to illustrate the dynamic_cast
#include <iostream>
using namespace std;

// Base Class
class Animal {
public:
    virtual void speak() const
    {
        cout << "Animal speaks." << endl;
    }
};

// Derived Class
class Dog : public Animal {
public:
    void speak() const override
    {
        cout << "Dog barks." << endl;
    }
};

// Derived Class
class Cat : public Animal {
public:
    void speak() const override
    {
        cout << "Cat meows." << endl;
    }
};

int main()
{
    // base class pointer to derived class object
    Animal* animalPtr = new Dog();

    // downcasting
    Dog* dogPtr = dynamic_cast<Dog*>(animalPtr);

    // checking if the typecasting is successfull
    if (dogPtr) {
        dogPtr->speak();
    }
    else {
        cout << "Failed to cast to Dog." << endl;
    }

    // typecasting to other dervied class
    Cat* catPtr = dynamic_cast<Cat*>(animalPtr);
    if (catPtr) {
        catPtr->speak();
    }
    else {
        cout << "Failed to cast to Cat." << endl;
    }

    delete animalPtr;
    return 0;
}

Output
Dog barks.
Failed to cast to Cat.

Explanation: The first line of output is printed because the ‘animalPtr’ of the ‘Animal’ type is successfully cast to the ‘Dog’ type and speak() function of the Dog class is invoked but the casting of the ‘Animal’ type to ‘Cat’ type is failed because ‘animalPtr’ points to a ‘Dog’ object thus, the dynamic cast fails because the typecasting is not safe.

3. const_cast

The const_cast operator is used to modify the const or volatile qualifier of a variable. It allows programmers to temporarily remove the constancy of an object and make modifications. Caution must be exercised when using const_cast, as modifying a const object can lead to undefined behavior.

Syntax for const_cast

const_cast <new_type> (expression);

Example of const_cast

C++
// C++ program to illustrate the const_cast
#include <iostream>
using namespace std;

int main()
{

    const int number = 5;
    // Pointer to a const int
    const int* ptr = &number;

    // int* nonConstPtr = ptr; if we use this
    // instead of without using const_cast
    // we will get error of invalid conversion
    int* nonConstPtr = const_cast<int*>(ptr);
    *nonConstPtr = 10;

    cout << "Modified number: " << *nonConstPtr;

    return 0;
}

Output
Modified number: 10

In the above example, we have modified the value of the const type pointer by changing its qualifier from const to non-const and then printing the modified value.

4. reinterpret_cast

The reinterpret_cast operator is used to convert the pointer to any other type of pointer. It does not perform any check whether the pointer converted is of the same type or not.

Syntax of reinterpret_cast

reinterpret_cast <new_type> (expression);

Example

C++
// C++ program to illustrate the reinterpret_cast
#include <iostream>
using namespace std;

int main()
{
    int number = 10;
    // Store the address of number in numberPointer
    int* numberPointer = &number;

    // Reinterpreting the pointer as a char pointer
    char* charPointer
        = reinterpret_cast<char*>(numberPointer);

    // Printing the memory addresses and values
    cout << "Integer Address: " << numberPointer << endl;
    cout << "Char Address: "
         << reinterpret_cast<void*>(charPointer) << endl;

    return 0;
}

Output
Integer Address: 0x7fff64789f1c
Char Address: 0x7fff64789f1c

In the above example, we have defined an int variable ‘number’ and then store the address of ‘number’ in ‘numberPointer’ of the int type after that we have converted the ‘numberPointer’ of the int type into char pointer and then store it into ‘charPointer’ variable. To verify that we have printed the address of both numberPointer and charPointer. To print the address stored in ‘charPointer’ reinterpret_cast<void*> is used to bypass the type-checking mechanism of C++ and allow the pointer to be printed as a generic memory address without any type-specific interpretation.

Note: const_cast and reinterpret_cast are generally not reccommended as they vulnerable to different kinds of errors.



Like Article
Suggest improvement
Previous
Next
Share your thoughts in the comments

Similar Reads