Vous l'avez étiqueté avec trois langues, et les réponses sont vraiment très différentes entre les trois. La discussion de C ++ implique plus ou moins une discussion sur les castes en C, ce qui donne (plus ou moins) une quatrième réponse.
Comme c'est celui que vous n'avez pas mentionné explicitement, je vais commencer par C. Les castings ont un certain nombre de problèmes. La première est qu'ils peuvent faire n'importe laquelle de plusieurs choses différentes. Dans certains cas, le casting ne fait rien de plus que de dire au compilateur (en substance): "tais-toi, je sais ce que je fais" - c'est-à-dire qu'il garantit que même lorsque vous effectuez une conversion qui pourrait causer des problèmes, le compilateur ne vous avertira pas de ces problèmes potentiels. Juste par exemple char a=(char)123456;
,. Le résultat exact de cette implémentation défini (dépend de la taille et de la signature dechar
), et sauf dans des situations plutôt étranges, n'est probablement pas utile. Les casts C varient également selon qu'il s'agit de quelque chose qui ne se produit qu'au moment de la compilation (c'est-à-dire que vous dites simplement au compilateur comment interpréter / traiter certaines données) ou quelque chose qui se produit au moment de l'exécution (par exemple, une conversion réelle de double à longue).
C ++ tente de traiter cela au moins dans une certaine mesure en ajoutant un certain nombre de «nouveaux» opérateurs de conversion, dont chacun est limité à seulement un sous-ensemble des capacités d'un cast C. Cela rend plus difficile (par exemple) de faire accidentellement une conversion que vous n'aviez vraiment pas l'intention - si vous avez seulement l' intention de rejeter la constness sur un objet, vous pouvez l'utiliser const_cast
, et assurez-vous que la seule chose que cela puisse affecter est de savoir si un objet est const
, volatile
ou non. Inversement, a static_cast
n'est pas autorisé à affecter si un objet est const
ouvolatile
. En bref, vous avez la plupart des mêmes types de capacités, mais elles sont catégorisées de sorte qu'une distribution ne peut généralement effectuer qu'un seul type de conversion, où une seule distribution de style C peut effectuer deux ou trois conversions en une seule opération. La principale exception est que vous pouvez utiliser un dynamic_cast
à la place d'un static_cast
dans au moins certains cas et bien qu'il soit écrit en tant que dynamic_cast
, il finira vraiment par devenir un static_cast
. Par exemple, vous pouvez utiliser dynamic_cast
pour parcourir une hiérarchie de classes vers le haut ou vers le bas - mais une conversion «vers le haut» de la hiérarchie est toujours sûre, donc cela peut être fait de manière statique, tandis qu'une conversion «vers le bas» de la hiérarchie n'est pas nécessairement sûre, donc c'est fait dynamiquement.
Java et C # sont beaucoup plus similaires l'un à l'autre. En particulier, avec les deux, la coulée est (pratiquement?) Toujours une opération d'exécution. En termes d'opérateurs de cast C ++, il est généralement plus proche de a dynamic_cast
en termes de ce qui est vraiment fait - c'est-à-dire que lorsque vous essayez de convertir un objet en un type de cible, le compilateur insère une vérification à l'exécution pour voir si cette conversion est autorisée , et lancez une exception si ce n'est pas le cas. Les détails exacts (par exemple, le nom utilisé pour l'exception de «mauvaise distribution») varient, mais le principe de base reste essentiellement similaire (bien que, si la mémoire est int
bonne , Java effectue des transtypages appliqués aux quelques types non-objets comme beaucoup plus proches de C casts - mais ces types sont assez rarement utilisés pour que 1) je ne m'en souviens pas avec certitude, et 2) même si c'est vrai, cela n'a pas beaucoup d'importance de toute façon).
En regardant les choses plus généralement, la situation est assez simple (du moins IMO): un casting (évidemment assez) signifie que vous convertissez quelque chose d'un type à un autre. Quand / si vous faites cela, cela soulève la question "Pourquoi?" Si vous voulez vraiment que quelque chose soit d'un type particulier, pourquoi ne l'avez-vous pas défini comme étant ce type pour commencer? Cela ne veut pas dire qu'il n'y a jamais de raison de faire une telle conversion, mais chaque fois que cela se produit, cela devrait poser la question de savoir si vous pouvez reconcevoir le code pour que le type correct soit utilisé partout. Même les conversions apparemment anodines (par exemple, entre un nombre entier et une virgule flottante) devraient être examinées beaucoup plus attentivement que ce qui est courant. Malgré leur apparencesimilitude, les entiers devraient vraiment être utilisés pour les types de choses «comptés» et la virgule flottante pour les types de choses «mesurées». Ignorer la distinction est ce qui conduit à certaines des déclarations folles comme «la famille américaine moyenne a 1,8 enfants». Même si nous pouvons tous voir comment cela se produit, le fait est qu'aucune famille n'a 1,8 enfant. Ils peuvent avoir 1 ou 2 ou ils peuvent en avoir plus - mais jamais 1.8.