Antworten:
Verstehen Sie zunächst, dass diese Zeilen nicht gleichwertig sind .
int* anInt = (int*)aFloat; // is equivalent to
int* anInt = reinterpret_cast<int*>(aFloat);
Was hier passiert, ist, dass der Programmierer den Compiler auffordert, alles zu tun, um die Besetzung vorzunehmen.
Der Unterschied ist wichtig, da bei Verwendung von static_cast nur ein "sicherer" Basistyp erforderlich ist, in den reinterpret_cast konvertiert werden kann, indem möglicherweise nur das gewünschte Speicherlayout auf den Speicher des angegebenen Objekts abgebildet wird.
Da der "Filter" nicht derselbe ist, ist die Verwendung einer bestimmten Besetzung klarer und sicherer als die Verwendung der C-Besetzung, wenn Sie sich auf den Compiler verlassen (oder auf die Laufzeitimplementierung, wenn Sie dynamic_cast verwenden), um zu erfahren, wo Sie etwas falsch gemacht haben , durch Umgehen von C cast und reinterepret_cast.
Nun, da dies klarer ist, gibt es noch eine andere Sache: static_cast, reinterpret_cast, const_cast und dynamic_cast sind einfacher zu suchen .
Und der letzte Punkt: Sie sind hässlich . Das ist gewollt. Möglicherweise fehlerhafter Code, Codegerüche, offensichtliche "Tricks", die Fehler erzeugen könnten, sind leichter zu verfolgen, wenn sie mit hässlichem Aussehen in Verbindung gebracht werden. Schlechter Code sollte hässlich sein .
Das ist "mit Absicht". Auf diese Weise kann der Entwickler erkennen, wo er die Dinge hätte besser machen können (indem er Abgüsse vollständig vermeidet, wenn sie nicht wirklich benötigt werden) und wo es in Ordnung ist, aber es wird im Code "dokumentiert", indem er es als hässlich "markiert".
Ein zweiter Grund für die Einführung der neuen Besetzung war, dass C-Besetzungen in einem Programm sehr schwer zu erkennen sind. Beispielsweise können Sie nicht bequem mit einem normalen Editor oder Textverarbeitungsprogramm nach Besetzungen suchen. Diese Unsichtbarkeit von Gipsabdrücken im C-Stil ist besonders bedauerlich, da sie so potenziell schädlich sind. Eine hässliche Operation sollte eine hässliche syntaktische Form haben. Diese Beobachtung war Teil des Grundes für die Wahl der Syntax für die Casts neuen Stils. Ein weiterer Grund war, dass die Darstellungen im neuen Stil der Schablonennotation entsprachen, sodass Programmierer ihre eigenen Darstellungen schreiben konnten, insbesondere zur Laufzeit überprüfte Darstellungen.
Vielleicht, weil static_cast so hässlich und relativ schwer zu tippen ist, ist es wahrscheinlicher, dass Sie zweimal darüber nachdenken, bevor Sie eines verwenden? Das wäre gut, denn in modernem C ++ sind Casts eigentlich meist vermeidbar.
C ++ - Casts sind restriktiver (drücken Sie Ihre Absichten also besser aus und erleichtern Sie die Codeüberprüfung usw.). Sie sind auch viel einfacher zu suchen, wenn Sie es jemals brauchen.
Option C: Eine Besetzung im "C ++ - Stil", da sie nicht von einer Konstruktion zu unterscheiden ist:
int anInt = int(aFloat);
oder auch:
int anInt(aFloat);
Abgesehen von diesen trivialen Fällen mit Primitiven, die gut verstanden werden, bevorzuge ich x_casts gegenüber C-Casts. Dafür gibt es drei Gründe:
Sie definieren die Operation, die der Programmierer ausführen wollte, enger.
Sie können Aktionen ausführen, die C-Casts nicht können (insbesondere im Fall von dynamic_cast <>, bei dem ein Cross-Cast über Zweige einer Mehrfachvererbungskette ausgeführt werden kann).
Sie sind hässlich . Sie erklären lautstark, dass der Programmierer gegen das Typsystem arbeitet. In diesem Fall ist es eine gute Sache.
Wenn Sie Code in C schreiben, verwenden Sie einen C-Cast. Wenn Sie in C ++ schreiben, verwenden Sie eine C ++ - Besetzung.
Während die meisten Castings die richtige Typensicherheit verletzen, sind die C ++ restriktiver und daher etwas weniger typensicher als bei einem C-Casting.
Ich kann es tolerieren, dass jemand (T *) NULL verwendet, um eine Überladung zu erzwingen ...
Ich habe ein paar Regeln für C / C ++ - Darstellungen:
const_cast
. Aus offensichtlichen Gründen. Leider wurde meine Regel, eine Konstante zu entfernen, die dazu führt, dass die Tastatur nach oben greift und dem Programmierer den Finger bricht, nicht akzeptiert.reinterpret_cast
. Es ist wirklich die Art von Besetzung, die C nicht hat: Stellen Sie sich vor, die Bits dieser ganzen Zahl seien die Bits eines Floats. Dies vermeidet Unannehmlichkeiten wie (int)(*(int*)(&floatVar))
.dynamic_cast
" eingeben, beenden Sie die polymorphe Klassenhierarchie und das Design und werten Sie sie erneut aus. Bewerten Sie den Entwurf Ihrer Klassenhierarchie erneut, bis Sie diese Wörter löschen können.static_cast
.Die Argumentation hinter # 4 ist einfach, dass es egal ist. Die Umstände, die nicht in die anderen Regeln passen, sind entweder offensichtlich oder sehr niedrig. Eine verständliche Konvertierung einfacher Typen wie int-to-float sollte keine spezielle Syntax erfordern. Und wenn Sie unten in den tiefen, hässlichen Eingeweiden von etwas sind, dann sind Sie unten in den tiefen, hässlichen Eingeweiden von etwas. Es ist nicht nötig, die Aufmerksamkeit auf die Tatsache zu lenken, dass "hier sind Drachen", da die Zähne, Klauen und das Feuer es schon so ziemlich verraten haben.
dynamic_cast
ist ein perfekt gültiges Werkzeug. Selten nützlich, gebe ich zu, aber es ist weit entfernt vom Satan von Dingen wie globalen Variablen. In erster Linie habe ich Sie jedoch herabgestimmt, weil Sie die Frage , ob C-Casts verwendet werden oder nicht, nicht beantwortet haben .
Wie in den obigen Beiträgen erwähnt, ist die C ++ - (statische) Umwandlung in der Praxis etwas sicherer.
Es könnte klug sein, mehr Informationen über die verschiedenen Arten von Castings und deren Vor- und Nachteile zu suchen.
Nur um mehr über das Warum zu erfahren. .
http://en.wikipedia.org/wiki/Static_cast
Es kommt wirklich darauf an, mit welcher Sprache ich arbeite, denn Sie wissen, was sie sagen: In Rom sprechen Sie Roman. Wenn ich also in C programmiere, versuche ich, die C-Funktionen maximal zu nutzen, aber wenn ich in C ++ programmiere, verwende ich die C ++ - Funktionen maximal, auch wenn einige Leute diesen Ansatz aus diesem Grund nicht mögen Sie sagen, es macht den Code "weniger portabel", ich sage, dass es mich nicht interessiert, ich bin in C ++ und programmiere in C ++, und ich brauche einen vollständig C ++ kompatiblen Compiler, um Code zu kompilieren, sonst würde ich mit etwas anderem arbeiten an erster Stelle.
static_cast usw. wurden aufgrund von Problemen mit den C-Darstellungen bei der Verwendung in Vorlagen erfunden. Wenn Sie eine Vorlage schreiben oder wenn der Code später möglicherweise in eine Vorlage konvertiert wird, empfiehlt es sich, Darstellungen im C ++ - Stil zu verwenden. Der Grund dafür ist, dass die C ++ - Darstellungen die Absicht besser ausdrücken und in Fällen, in denen C-Darstellungen das Falsche tun (bei bestimmten Typen als Vorlagenparameter), die erwarteten Ergebnisse liefern.
Abgesehen davon, sage ich, verwenden Sie C ++ - Casts, wenn Sie ein bestimmtes Problem haben, das diese benötigt - dynamic_cast ist das häufigste, aber selbst das ist wahrscheinlich nicht alltäglich.
Alles andere und eine Besetzung im C-Stil sind möglicherweise weniger unübersichtlich und tragen zur besseren Lesbarkeit bei, oder auch nicht, je nachdem, wie vertraut der Leser mit diesem Besetzungsstil heutzutage ist. Es ist aus meiner Sicht nicht wirklich wichtig, hauptsächlich eine persönliche Präferenzsache, aber wundern Sie sich nicht, wenn manche Leute den C-Stil nicht mögen.
Letzte Anmerkung: Wenn Sie so viele Casts benötigen, dass dies eine große Sache ist, machen Sie wahrscheinlich etwas anderes falsch. In einigen Fällen gibt es Ausnahmen, aber für die meisten High-Level-Codes sollten nicht viele (wenn überhaupt) Casts erforderlich sein.
reinterpret_cast<int>(double);
. Es ist durchaus möglich, ein Double mit einer C-Besetzung in ein Int umzuwandeln, aber mit reinterpret_cast ist dies nicht möglich. Ich sehe, Timbo hat Sie bereits darauf hingewiesen, und Sie sagten, Sie würden es reparieren, aber vier Jahre später bleibt es falsch. Ich würde Sie trotzdem ablehnen, wenn dies behoben wäre, da es durchaus berechtigte Gründe gibt, eine Besetzung zu benötigen. Hier ist eine bessere Antwort: stackoverflow.com/a/332086/3878168