const_cast en C++ | Tipo Operadores de fundición

C++ admite los siguientes 4 tipos de operadores de conversión:

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

1. const_cast
const_cast se usa para desechar la constness de las variables. Los siguientes son algunos datos interesantes sobre const_cast.

1) const_cast se puede usar para cambiar miembros de clase no const dentro de una función de miembro const. Considere el siguiente fragmento de código. Dentro de la función miembro const fun(), el compilador trata ‘esto’ como ‘estudiante const* const esto’, es decir, ‘esto’ es un puntero constante a un objeto constante, por lo que el compilador no permite cambiar los miembros de datos a través de puntero ‘este’. const_cast cambia el tipo de puntero ‘this’ a ‘student* const this’.

#include <iostream>
using namespace std;
  
class student
{
private:
    int roll;
public:
    // constructor
    student(int r):roll(r) {}
  
    // A const function that changes roll with the help of const_cast
    void fun() const
    {
        ( const_cast <student*> (this) )->roll = 5;
    }
  
    int getRoll()  { return roll; }
};
  
int main(void)
{
    student s(3);
    cout << "Old roll number: " << s.getRoll() << endl;
  
    s.fun();
  
    cout << "New roll number: " << s.getRoll() << endl;
  
    return 0;
}

Producción:

Old roll number: 3
New roll number: 5

2) const_cast se puede usar para pasar datos const a una función que no recibe const. Por ejemplo, en el siguiente programa, fun() recibe un puntero normal, pero se puede pasar un puntero a const con la ayuda de const_cast.

#include <iostream>
using namespace std;
  
int fun(int* ptr)
{
    return (*ptr + 10);
}
  
int main(void)
{
    const int val = 10;
    const int *ptr = &val;
    int *ptr1 = const_cast <int *>(ptr);
    cout << fun(ptr1);
    return 0;
}

Producción:

20

3) Es un comportamiento indefinido modificar un valor que inicialmente se declara como const. Considere el siguiente programa. La salida del programa no está definida. La variable ‘val’ es una variable const y la llamada ‘fun(ptr1)’ intenta modificar ‘val’ usando const_cast.

#include <iostream>
using namespace std;
  
int fun(int* ptr)
{
    *ptr = *ptr + 10;
    return (*ptr);
}
  
int main(void)
{
    const int val = 10;
    const int *ptr = &val;
    int *ptr1 = const_cast <int *>(ptr);
    fun(ptr1);
    cout << val;
    return 0;
}

Producción:

 Undefined Behavior 

Está bien modificar un valor que inicialmente no está declarado como const. Por ejemplo, en el programa anterior, si eliminamos const de la declaración de val, el programa producirá 20 como salida.

#include <iostream>
using namespace std;
  
int fun(int* ptr)
{
    *ptr = *ptr + 10;
    return (*ptr);
}
  
int main(void)
{
    int val = 10;
    const int *ptr = &val;
    int *ptr1 = const_cast <int *>(ptr);
    fun(ptr1);
    cout << val;
    return 0;
}

4) const_cast se considera más seguro que la conversión de tipo simple. Es más seguro en el sentido de que el lanzamiento no sucederá si el tipo de lanzamiento no es el mismo que el del objeto original. Por ejemplo, el siguiente programa falla en la compilación porque ‘int *’ se está encasillando en ‘char *’

#include <iostream>
using namespace std;
  
int main(void)
{
    int a1 = 40;
    const int* b1 = &a1;
    char* c1 = const_cast <char *> (b1); // compiler error
    *c1 = 'A';
    return 0;
}

producción:

prog.cpp: In function ‘int main()’:
prog.cpp:8: error: invalid const_cast from type 'const int*' to type 'char*'

5) const_cast también se puede usar para desechar atributos volátiles. Por ejemplo, en el siguiente programa, el typeid de b1 es PVKi (puntero a un entero volátil y constante) y el typeid de c1 es Pi (puntero a un entero)

#include <iostream>
#include <typeinfo>
using namespace std;
  
int main(void)
{
    int a1 = 40;
    const volatile int* b1 = &a1;
    cout << "typeid of b1 " << typeid(b1).name() << '\n';
    int* c1 = const_cast <int *> (b1);
    cout << "typeid of c1 " << typeid(c1).name() << '\n';
    return 0;
}

Producción:

typeid of b1 PVKi
typeid of c1 Pi

Ejercicio
Prediga la salida de los siguientes programas. Si hay errores de compilación, corríjalos.

Pregunta 1

#include <iostream>
using namespace std;
  
int main(void)
{
    int a1 = 40;
    const int* b1 = &a1;
    char* c1 = (char *)(b1);
    *c1 = 'A';
    return 0;
}

Pregunta 2

#include <iostream>
using namespace std;
  
class student
{
private:
    const int roll;
public:
    // constructor
    student(int r):roll(r) {}
  
    // A const function that changes roll with the help of const_cast
    void fun() const
    {
        ( const_cast <student*> (this) )->roll = 5;
    }
  
    int getRoll()  { return roll; }
};
  
int main(void)
{
    student s(3);
    cout << "Old roll number: " << s.getRoll() << endl;
  
    s.fun();
  
    cout << "New roll number: " << s.getRoll() << endl;
  
    return 0;
}

—Aashish Barnwal . Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema tratado anteriormente.

Publicación traducida automáticamente

Artículo escrito por GeeksforGeeks-1 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *