Conversiones de Tipo en C++

420 palabras 3 minutos C++

Las conversiones de tipo (o type casting) permiten transformar un valor de un tipo de dato en otro. Son una herramienta fundamental en C++, pero también una fuente frecuente de errores si se utilizan incorrectamente.

En este artículo repasaremos las conversiones implícitas y explícitas, junto con los distintos operadores de conversión disponibles en C++ moderno.


Conversiones Implícitas

El compilador puede realizar algunas conversiones automáticamente cuando considera que son seguras.

int entero = 10;
double decimal = entero; // int -> double

Salida:

10.0

En este caso no hay pérdida de información porque un double puede representar perfectamente un entero pequeño.


Conversiones con Pérdida de Datos

No todas las conversiones son seguras.

double precio = 19.99;
int entero = precio;

Resultado:

19

La parte decimal se pierde.


Cast Estilo C

La forma tradicional heredada de C es:

double precio = 19.99;
int entero = (int)precio;

Aunque funciona, en C++ moderno se recomienda evitarla porque es menos clara y puede ocultar errores.


static_cast

Es la conversión más utilizada en C++ moderno.

double precio = 19.99;

int entero = static_cast<int>(precio);

std::cout << entero << std::endl;

Salida:

19

Ventajas:

  • Más legible.
  • Más segura que el cast estilo C.
  • Permite detectar errores en compilación.

Conversión entre Tipos Numéricos

int a = 10;
float b = static_cast<float>(a);

std::cout << b << std::endl;

Salida:

10

Conversión de Caracteres

Los caracteres son internamente números.

char letra = 'A';

int codigo = static_cast<int>(letra);

std::cout << codigo << std::endl;

Salida:

65

Y viceversa:

int codigo = 66;

char letra = static_cast<char>(codigo);

std::cout << letra << std::endl;

Salida:

B

Conversión de Punteros

static_cast puede convertir punteros relacionados mediante herencia.

class Animal
{
public:
    virtual ~Animal() = default;
};

class Perro : public Animal
{
};

Perro perro;

Animal* animal = static_cast<Animal*>(&perro);

dynamic_cast

Se utiliza cuando se trabaja con polimorfismo y se necesita verificar el tipo real del objeto.

Animal* animal = new Perro();

Perro* perro = dynamic_cast<Perro*>(animal);

if (perro)
{
    std::cout << "Conversion exitosa" << std::endl;
}

Si la conversión falla, devuelve nullptr.


reinterpret_cast

Permite reinterpretar los bits de una variable como otro tipo.

int numero = 65;

char* ptr = reinterpret_cast<char*>(&numero);

Este cast es extremadamente potente y también extremadamente peligroso.

Se utiliza principalmente para:

  • Programación de sistemas.
  • Drivers.
  • Protocolos binarios.
  • Serialización de bajo nivel.

En aplicaciones normales suele ser mejor evitarlo.


const_cast

Permite agregar o quitar el modificador const.

const int valor = 10;

int* ptr = const_cast<int*>(&valor);

Debe utilizarse con mucho cuidado. Modificar un objeto originalmente declarado como const produce comportamiento indefinido.


Conversión de Enumeraciones

enum Estado
{
    Activo = 1,
    Inactivo = 2
};

Estado e = Activo;

int valor = static_cast<int>(e);

Salida:

1

Conversión de void*

Muy común en APIs antiguas y bibliotecas en C.

int numero = 42;

void* ptr = &numero;

int* entero = static_cast<int*>(ptr);

std::cout << *entero << std::endl;

Salida:

42

Conversión Definida por el Usuario

Una clase puede definir cómo convertirse a otro tipo.

class Peso
{
private:
    double valor;

public:
    Peso(double v) : valor(v)
    {
    }

    operator double() const
    {
        return valor;
    }
};

Peso p(10.5);

double kg = p;

Salida:

10.5

Buenas Prácticas

✅ Preferir static_cast sobre el cast estilo C.

✅ Usar dynamic_cast cuando se necesite verificar tipos en jerarquías polimórficas.

✅ Evitar reinterpret_cast salvo que realmente se comprenda lo que está ocurriendo a nivel de memoria.

✅ Evitar eliminar const con const_cast.

✅ Activar todas las advertencias del compilador (-Wall -Wextra en GCC/Clang).


Resumen

C++ ofrece varios mecanismos de conversión, cada uno diseñado para situaciones específicas:

ConversiónUso Principal
static_castConversión segura entre tipos relacionados
dynamic_castVerificación de tipos en herencia polimórfica
reinterpret_castReinterpretación de memoria
const_castAgregar o quitar const
Cast estilo CCompatibilidad heredada (no recomendado)

En la mayoría de las aplicaciones modernas, static_cast cubre prácticamente todas las necesidades habituales y debería ser tu primera opción al realizar conversiones explícitas.