4.9.9a El operador const_cast
§1 Sinopsis:
La palabra clave const_cast identifica un operador de uso muy específico: sirve para poner o quitar los atributos const o volatile de un objeto. La sintaxis general es:
const_cast< T > (arg)
En la expresión anterior, T y arg deben ser del mismo tipo, excepto en los atributos const ( 3.2.1c ) y volatile ( 4.1.9). T es el tipo al que se quiere convertir, arg es el tipo de partida (ver ejemplo). El modelado es resuelto en tiempo de compilación, y el resultado es del tipo T. Una sola expresión const_cast puede poner o quitar el atributo const o volatile a cualquier número de objetos.
Ejemplo
const int x = 10;
int* iptr = &x; // Error!!
Un intento de compilar las sentencias anteriores conduce a un error del compilador:
invalid conversion from `const int*' to `int*'
La razón es que se está intentando asignar la dirección de un int-const a un puntero-a-int, cuando se necesitaría un puntero-a-int-const. Suponiendo que no queramos (o podamos) cambiar la definición de iptr, el problema de la asignación en la segunda línea puede resolverse mediante un "casting" adecuado:
const int x = 23;
int* iptr = const_cast<int*> (&x); // Ok!!
§2 cons_cast con punteros
El cambio de atributo puede utilizarse con punteros, de forma que un puntero a-tipoX-constante puede ser convertido en puntero a-tipoX y viceversa. El cambio también puede realizarse con un puntero a-tipoX-volatile.
El puntero obtenido es idéntico al original en todos los demás aspectos. Si la conversión tiene éxito el puntero resultante señala al mismo objeto que el original. Ejemplo:
const int kte = 35;
int* ptr;
ptr = &kte;
// Error!
ptr = (int*) &kte;
// modelado antiguo desaconsejado
ptr = const_cast<int*> (&kte); // Ok:
volatile int x = 45;
ptr = &x;
// Error!
ptr = const_cast<int*> (&x); // Ok:
Así pues, este operador convierte un objeto (o referencia a objeto) const o volatile en un objeto (o
referencia) no-const o no-volatile que es idéntico en lo demás al original.
Es importante advertir que el operador const_cast no cambia el tipo del operando, lo que significa que este operador no hace que una variable constante pueda volverse no-constante y ver alterado su valor después de aplicado el operador. Considere detenidamente el resultado obtenido en el siguiente ejemplo, e intente llegar a una explicación (recuerde lo señalado al respecto en 4.2.1e).
#include <iostream.h>
int main() {
const int x = 35;
// constante iniciada a 35
int* ptr; // puntero a entero
ptr = const_cast<int*> (&x); // Ok: (gracias al 'casting')
cout << "Valor x = " << *ptr << endl;
*ptr = 100;
// Se asigna un valor a x ?!!
cout << "Valor x = " << *ptr << endl;
cout << "Valor x = " << x << endl;
int z = 10 + x;
// Comprobación del valor de x
cout << "x + 10 = " << z << endl;
}
Salida:
Valor x = 35
Valor x = 100
Valor x = 35
x + 10 = 45