C++

C++ : const_cast and reinterpret_cast

Typecasting is frequently used in C++ programming. Typecasting is used to tell the compiler that, even though the object is of one type, treat the object like some other type.

C++ provides the below types for casting

Casting Operators : const_cast
Syntax : const_cast <type> (Expression)
const_cast takes away the constness of its expression.
- const_cast is a keyword.
- type could be a reference or a pointer

C++ program to demonstrate const_cast.
In the below program, ‘a’ being a constant integer, &a cannot be assigned to int*. Doing so gives a compilation error.

#include<iostream>

using namespace std;

int main() {

    const int a = 10; 
    int *ptr_to_a = &a; 

    cout << "Value of a : " << *ptr_to_a << endl;

    return 0;
}

Output

$ g++ example.cpp 
example.cpp: In function ‘int main()’:
example.cpp:8:21: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
    8 |     int *ptr_to_a = &a;
      |                     ^~
      |                     |
      |                     const int*


const_cast should be used to cast away the const-ness from pointer / reference that refers to something that is not const.

In the below program, we use a const_cast to change a class data member inside a constant function where the values being pointed to by this pointer are not allowed to change.

#include<iostream>

using namespace std;

class Employee {

    private:
    int emp_id = 1;
    public :
    void Display_Employee_Id() const {
        cout << "Original Employee Id : " << emp_id << endl;
        Employee * emp_ptr = const_cast<Employee*>(this);
        emp_ptr->emp_id = 100;
        cout << "Modified Employee Id : " << emp_id << endl;
    }
};

int main() {

    const int a = 10;
    int *ptr_to_a = const_cast<int*> (&a);
    cout << "Value of a : " << *ptr_to_a << endl;
    // Modifying a const variable could result in an 
    // undefined behavior and not recommended.
    // *ptr_to_a += 10;
    // cout << "Value of a : " << *ptr_to_a << endl;

    Employee e;
    e.Display_Employee_Id();

    int b = 20;
    cout << "Value of b : " << b << endl;

    // Modifying a non-const variable using a const_cast on pointer / reference is totally fine
    // and does not result in undefined behavior.
    const int& ref_b = b;
    const_cast<int&>(ref_b) = 40;
    cout << "Value of b : " << b << endl;

    const int* ptr_b = &b;
    * const_cast<int*>(ptr_b) = 60;
    cout << "Value of b : " << b << endl;

    return 0;
}

Output

Value of a : 10
Original Employee Id : 1
Modified Employee Id : 100
Value of b : 20
Value of b : 40
Value of b : 60

Casting Operators : reinterpret_cast
Syntax : reinterpret_cast <type> (Expression)
reinterpret_cast performs a low level reinterpretation of the bit pattern of its operands.
- reinterpret_cast is a keyword.
- type is a pointer reinterpreted as.
- Expression is a pointer to be reinterpreted.

Below C++ program demonstrates the use of reinterpret_cast to reinterpret the bit pattern.

#include<iostream>
#include<string>

using namespace std;

class SolarSystem {
    
    public:
    int planets;
    int stars;
    string name;
    bool visible;
    SolarSystem (int v_planets, int v_stars, string v_name, bool v_visible): \
                planets(v_planets),stars(v_stars),name(v_name),visible(v_visible) {

    }   
};

int main() {

    SolarSystem sobj(9, 1, "Milky Way", true);

    int* int_ptr;
    int_ptr = reinterpret_cast<int*>(&sobj.planets);
    cout << "Planets : " << *int_ptr << endl;
    int_ptr++;
    cout << "Stars : " << *int_ptr << endl;
    int_ptr++;

    string* string_ptr;
    string_ptr = reinterpret_cast<string*>(int_ptr);
    cout << "Galaxy : " << *string_ptr << endl;
    string_ptr++;
 
    bool* bool_ptr;
    bool_ptr = reinterpret_cast<bool*>(string_ptr);
    cout << "Visible : " << *bool_ptr << endl;

    return 0;
}

Output

Planets : 9
Stars : 1
Galaxy : Milky Way
Visible : 1


Copyright (c) 2019-2021, Algotree.org.
All rights reserved.