Ha etiquetado esto con tres idiomas, y las respuestas son muy diferentes entre los tres. La discusión de C ++ implica más o menos también la discusión de las conversiones de C, y eso da (más o menos) una cuarta respuesta.
Dado que es el que no mencionaste explícitamente, comenzaré con C. Los yesos C tienen varios problemas. Una es que pueden hacer varias cosas diferentes. En algunos casos, el elenco no hace más que decirle al compilador (en esencia): "Cállate, sé lo que estoy haciendo", es decir, asegura que incluso cuando realizas una conversión que podría causar problemas, el compilador no le advertirá sobre esos problemas potenciales. Solo por ejemplo char a=(char)123456;
,. El resultado exacto de esta implementación definida (depende del tamaño y firma dechar
), y excepto en situaciones bastante extrañas, probablemente no sea útil. Las conversiones de C también varían en cuanto a si son algo que sucede solo en tiempo de compilación (es decir, solo le está diciendo al compilador cómo interpretar / tratar algunos datos) o algo que sucede en tiempo de ejecución (por ejemplo, una conversión real de doble a largo).
C ++ intenta lidiar con eso al menos en cierta medida agregando un número de operadores de conversión "nuevos", cada uno de los cuales está restringido a solo un subconjunto de las capacidades de una conversión de C. Esto hace que sea más difícil (por ejemplo) hacer accidentalmente una conversión que realmente no pretendía: si solo tiene la intención de deshacerse de la consistencia en un objeto, puede usar const_cast
y estar seguro de que lo único que puede afectar es si un objeto es const
, volatile
o no. Por el contrario, static_cast
no se permite que a afecte si un objeto es const
ovolatile
. En resumen, tiene la mayoría de los mismos tipos de capacidades, pero están categorizados de modo que un elenco generalmente solo puede hacer un tipo de conversión, donde un solo elenco de estilo C puede hacer dos o tres conversiones en una operación. La principal excepción es que puede usar un dynamic_cast
en lugar de un static_cast
en al menos algunos casos y, a pesar de estar escrito como un dynamic_cast
, realmente terminará como un static_cast
. Por ejemplo, puede utilizar dynamic_cast
para recorrer una jerarquía de clases hacia arriba o hacia abajo, pero un elenco "hacia arriba" en la jerarquía siempre es seguro, por lo que se puede hacer de forma estática, mientras que un elenco "hacia abajo" en la jerarquía no es necesariamente seguro, por lo que es hecho dinámicamente.
Java y C # son mucho más similares entre sí. En particular, con ambos, el casting es (¿virtualmente?) Siempre una operación en tiempo de ejecución. En términos de los operadores de dynamic_cast
conversión de C ++, generalmente está más cerca de lo que realmente se hace, es decir, cuando intenta lanzar un objeto a algún tipo de destino, el compilador inserta una verificación en tiempo de ejecución para ver si esa conversión está permitida y lanzar una excepción si no lo es. Los detalles exactos (p. Ej., El nombre utilizado para la excepción de "conversión incorrecta") varían, pero el principio básico sigue siendo en su mayor parte similar (aunque, si la memoria no funciona, Java hace que las conversiones se apliquen a los pocos tipos que no son objetos como int
mucho más cerca de C casts, pero estos tipos se usan tan raramente que 1) no lo recuerdo con seguridad, y 2) incluso si es cierto, no importa mucho de todos modos).
Mirando las cosas de manera más general, la situación es bastante simple (al menos en mi opinión): un elenco (obviamente) significa que estás convirtiendo algo de un tipo a otro. Cuando / si haces eso, surge la pregunta "¿Por qué?" Si realmente quieres que algo sea de un tipo en particular, ¿por qué no lo definiste como ese para empezar? Eso no quiere decir que nunca haya una razón para hacer tal conversión, pero cada vez que suceda, debería plantear la pregunta de si podría rediseñar el código para que se use el tipo correcto en todo momento. Incluso las conversiones aparentemente inocuas (por ejemplo, entre números enteros y punto flotante) deben examinarse mucho más de cerca de lo que es común. A pesar de su aparentesimilitud, los números enteros realmente deberían usarse para tipos de cosas "contados" y el punto flotante para tipos de cosas "medidos". Ignorar la distinción es lo que lleva a algunas de las declaraciones locas como "la familia estadounidense promedio tiene 1.8 hijos". Aunque todos podemos ver cómo sucede eso, el hecho es que ninguna familia tiene 1.8 hijos. Pueden tener 1 o 2 o pueden tener más que eso, pero nunca 1.8.