Sie haben dies mit drei Sprachen markiert, und die Antworten sind zwischen den drei wirklich sehr unterschiedlich. Die Diskussion über C ++ impliziert mehr oder weniger auch die Diskussion über C-Casts, und das gibt (mehr oder weniger) eine vierte Antwort.
Da es das ist, was Sie nicht explizit erwähnt haben, beginne ich mit C. C-Casts haben eine Reihe von Problemen. Zum einen können sie verschiedene Dinge tun. In einigen Fällen sagt die Besetzung lediglich dem Compiler (im Wesentlichen): "Halt die Klappe, ich weiß, was ich tue" - dh sie stellt sicher, dass der Compiler auch bei einer Konvertierung Probleme verursacht Ich werde Sie nicht vor diesen möglichen Problemen warnen. Nur zum Beispiel char a=(char)123456;
. Das genaue Ergebnis dieser Implementierung wird definiert (hängt von der Größe und Signatur von abchar
), und außer in ziemlich seltsamen Situationen, ist wahrscheinlich nicht nützlich. C-Casts unterscheiden sich auch darin, ob sie nur zur Kompilierungszeit (dh Sie sagen dem Compiler nur, wie einige Daten interpretiert / behandelt werden sollen) oder zur Laufzeit (z. B. eine tatsächliche Konvertierung von double in) erfolgen lange).
C ++ versucht, dies zumindest teilweise zu bewältigen, indem eine Reihe von "neuen" Cast-Operatoren hinzugefügt werden, von denen jeder nur auf eine Teilmenge der Funktionen eines C-Cast beschränkt ist. Dies macht es schwieriger, (zum Beispiel) versehentlich eine Konvertierung durchzuführen, die Sie wirklich nicht beabsichtigt haben. Wenn Sie nur beabsichtigen, die Konstanz eines Objekts zu beseitigen, können Sie sie verwenden const_cast
und sicherstellen, dass das einzige, was davon betroffen sein kann, ob ein Objekt ist const
, volatile
oder nicht. Umgekehrt static_cast
darf a nicht beeinflussen, ob ein Objekt ist const
oder nichtvolatile
. Kurz gesagt, Sie haben die meisten der gleichen Arten von Funktionen, aber sie sind kategorisiert, sodass eine Besetzung im Allgemeinen nur eine Art von Konvertierung durchführen kann, während eine einzelne Besetzung im C-Stil zwei oder drei Konvertierungen in einem Vorgang ausführen kann. Die primäre Ausnahme ist , dass Sie kann ein verwenden dynamic_cast
anstelle von einer static_cast
zumindest in einigen Fällen und obwohl sie geschrieben als dynamic_cast
, es wird wirklich als ein Ende static_cast
. Zum Beispiel können Sie dynamic_cast
eine Klassenhierarchie nach oben oder unten durchlaufen - aber ein Cast "up" der Hierarchie ist immer sicher, so dass dies statisch erfolgen kann, während ein Cast "down" die Hierarchie nicht unbedingt sicher ist, so ist es dynamisch gemacht.
Java und C # sind einander viel ähnlicher. Insbesondere bei beiden ist das Gießen (praktisch?) Immer eine Laufzeitoperation. In Bezug auf die C ++ - Cast-Operatoren ist es dynamic_cast
in Bezug auf das, was wirklich getan wird , normalerweise am nächsten an a. Wenn Sie also versuchen, ein Objekt in einen Zieltyp umzuwandeln, fügt der Compiler eine Laufzeitprüfung ein, um festzustellen, ob diese Konvertierung zulässig ist und eine Ausnahme auslösen, wenn dies nicht der Fall ist. Die genauen Details (z. B. der Name, der für die Ausnahme "Bad Cast" verwendet wird) variieren, aber das Grundprinzip bleibt größtenteils ähnlich (obwohl Java, wenn Speicher dient, Casts auf die wenigen Nicht-Objekttypen anwendet, die int
viel näher an C liegen Casts - aber diese Typen werden selten genug verwendet, dass 1) ich mich nicht sicher daran erinnere und 2) selbst wenn es wahr ist, es sowieso nicht viel ausmacht).
Wenn man die Dinge allgemeiner betrachtet, ist die Situation ziemlich einfach (zumindest IMO): Eine Besetzung (offensichtlich genug) bedeutet, dass Sie etwas von einem Typ in einen anderen konvertieren. Wann / wenn Sie das tun, wirft es die Frage "Warum?" Wenn Sie wirklich möchten, dass etwas ein bestimmter Typ ist, warum haben Sie es nicht zunächst als diesen Typ definiert? Das heißt nicht, dass es nie einen Grund gibt, eine solche Konvertierung durchzuführen, aber jedes Mal, wenn dies geschieht, sollte sich die Frage stellen, ob Sie den Code neu entwerfen können, sodass durchgehend der richtige Typ verwendet wurde. Selbst scheinbar harmlose Konvertierungen (z. B. zwischen Ganzzahl und Gleitkomma) sollten viel genauer als üblich untersucht werden. Trotz ihres AnscheinesÄhnlichkeit, Ganzzahlen sollten wirklich für "gezählte" Arten von Dingen und Gleitkomma für "gemessene" Arten von Dingen verwendet werden. Das Ignorieren der Unterscheidung führt zu einigen verrückten Aussagen wie "Die durchschnittliche amerikanische Familie hat 1,8 Kinder". Obwohl wir alle sehen können, wie das passiert, ist die Tatsache, dass keine Familie 1,8 Kinder hat. Sie könnten 1 oder sie könnten 2 haben oder sie könnten mehr als das haben - aber niemals 1.8.