Conversión de tipos definidos por el usuario

En C++, puedes definir tus propios tipos de datos mediante la creación de clases o estructuras. Cuando trabajas con tipos definidos por el usuario, es posible que necesites convertirlos a otros tipos de datos para realizar operaciones o asignaciones.

La conversión de tipos definidos por el usuario se puede lograr mediante dos enfoques: la conversión implícita y la conversión explícita.

Conversión implícita.- La conversión implícita ocurre automáticamente cuando se realiza una asignación o una operación entre tipos compatibles. En algunos casos, C++ puede realizar automáticamente una conversión implícita entre tipos relacionados si existe una conversión definida en el estándar del lenguaje o si se ha proporcionado una conversión personalizada en las clases o estructuras definidas por el usuario.

En este ejemplo, la clase MiClase tiene un operador de conversión definido que permite la conversión implícita de MiClase a un entero.

Al asignar objeto a la variable numero, se invoca automáticamente el operador de conversión, convirtiendo el objeto MiClase en un entero.

Conversión explícita.- La conversión explícita, también conocida como «casting«, se realiza utilizando operadores de casting específicos. Puedes utilizar los operadores de casting static_cast, dynamic_cast, reinterpret_cast y const_cast para realizar conversiones explícitas entre tipos definidos por el usuario.

En este ejemplo, se utiliza static_cast para realizar una conversión explícita del miembro valor de la clase MiClase a un entero.

Un ejemplo práctico:

En este ejemplo, declaramos una variable long a y una variable int b con un vbalor de 10 dentro de la función main().

Tenemos, a = b, que implica una conversión implícita del tipo int al tipo long. Dado que long es un tipo de dato de mayor tamaño y rango que int, el valor de b se asigna hacia a sin problemas.

Después de la asignación, imprimimos el valor de a en la pantalla. La salida será:

Ejemplo cuando se ejecuta una operación aritmética:

En este ejemplo, declaramos una variable a de tipo int con un valor de 5, y una variable b de tipo double con un valor de 2.5.

Luego, realizamos la multiplicación a * b, lo que implica una conversión implícita del tipo int al tipo double. Esto ocurre porque el operando a es de tipo int y el operando b es de tipo double, y C++ realiza la conversión implícita para realizar la operación aritmética. El resultado de la multiplicación se almacena en la variable resultado, que también es de tipo double.

Finalmente, imprimimos el valor de resultado.

Este ejemplo muestra cómo se realiza una conversión implícita al ejecutar una operación aritmética entre un tipo int y un tipo double. La conversión implícita permite que el resultado de la operación se ajuste al tipo del operando con mayor precisión.

El resultado será:

Ejemplo cuando se pasa un argumento a una función:

En este ejemplo, tenemos una función imprimirNumero() que recibe un parámetro de tipo double y simplemente imprime el número recibido.

En la función main(), declaramos una variable llamada valor de tipo int con un valor de 7.

Luego, llamamos a la función imprimirNumero(valor), pasando valor como argumento. Esto implica una conversión implícita de int al tipo double, ya que la función imprimirNumero() espera recibir un argumento de tipo double.

El resultado será la impresión del número 7 como 7.0, ya que el argumento se convierte en double.

Conversión mediante constructores

La conversión mediante constructores en C++ permite realizar conversiones explícitas e implícitas entre diferentes tipos de datos definidos por el usuario utilizando constructores. Al definir un constructor con un solo parámetro, se puede habilitar la conversión automática desde ese tipo de dato al tipo de la clase o estructura.

Veamos un ejemplo de cómo se puede realizar una conversión mediante constructores:

En este ejemplo, tenemos una clase llamada Punto que tiene dos miembros de datos x e y.

La clase Punto tiene dos constructores: uno que toma dos parámetros de tipo int y otro que toma dos parámetros de tipo double.

En la función main(), creamos dos objetos Punto. El primer objeto, punto1, se construye directamente utilizando el constructor que toma dos enteros.

El segundo objeto, punto2, se construye mediante una conversión implícita al utilizar el constructor que toma dos double.

C++ realiza una conversión automática de los double a int utilizando el operador de conversión static_cast en el constructor correspondiente.

Finalmente, imprimimos las coordenadas de ambos puntos. La salida será:

Operadores de conversión

Los operadores de conversión se utilizan para definir conversiones explícitas de un tipo de dato a otro. Estos operadores permiten que una clase o estructura definida por el usuario se comporte como otro tipo de dato cuando sea necesario. Los operadores de conversión se definen mediante la sobrecarga de operadores y se denominan funciones de conversión. Hay dos tipos principales de operadores de conversión en C++:

1.- Operador de conversión de tipo de dato único: Este operador se utiliza para convertir una clase a un solo tipo de dato. Se define utilizando la palabra clave operator seguida del tipo de dato de destino. Este tipo de operador se invoca explícitamente y puede ser utilizado para convertir objetos de la clase en el tipo de dato deseado.

2.- Operador de conversión de tipo de dato múltiple: Este operador se utiliza para convertir una clase a múltiples tipos de datos. Se define utilizando una función de conversión con el tipo de dato de destino como el tipo de retorno. Este tipo de operador se invoca automáticamente cuando se necesita una conversión implícita y no requiere una invocación explícita.

Aquí tienes un ejemplo que muestra la definición de ambos tipos de operadores de conversión:

En este ejemplo, la clase MiClase tiene un miembro de datos llamado valor de tipo entero.

La clase define tanto un operador de conversión de tipo de dato único

…como un operador de conversión de tipo de dato múltiple.

El operador de conversión de tipo de dato único se define como operator int() const, lo que permite que un objeto MiClase se convierta explícitamente a un entero. En el ejemplo, se utiliza static_cast(objeto) para invocar explícitamente este operador y convertir el objeto MiClase a un entero.

El operador de conversión de tipo de dato múltiple se define como operator double() const, lo que permite que un objeto MiClase se convierta implícitamente a un double. En el ejemplo, la conversión se realiza automáticamente al asignar el objeto MiClase a una variable de tipo double.

En la función main(), se muestra cómo invocar tanto el operador de conversión de tipo de dato único como el operador de conversión de tipo de dato múltiple.

Se imprimen los valores convertidos entero y decimal.

Ambigüedades

En la programación en C++, a veces puede haber ambigüedades cuando se utilizan operadores de conversión. Estas ambigüedades ocurren cuando hay múltiples operadores de conversión que podrían aplicarse a una expresión y el compilador no puede determinar cuál debería utilizarse.

Aquí tienes un ejemplo que muestra una ambigüedad en la conversión de tipos:

En este ejemplo, la clase MiClase tiene tanto un operador de conversión a int como un operador de conversión a double.

Luego, hay una función ImprimirNumero() que toma un parámetro de tipo double e imprime numero.

En la función main(), se crea un objeto MiClase llamado objeto con un valor de 5.

Luego, se intenta llamar a la función ImprimirNumero() pasando objeto como argumento.

Sin embargo, esto crea una ambigüedad en la conversión de tipos, ya que tanto el operador de conversión a int como el operador de conversión a double podrían aplicarse.