Was ist der Unterschied zwischen static_cast <> und C-Casting?

202

Gibt es einen Grund, static_cast<>Casting im C-Stil vorzuziehen ? Sind sie gleichwertig? Gibt es einen Geschwindigkeitsunterschied?

Dicroce
quelle
5
Siehe auch
Flow

Antworten:

217

Casts im C ++ - Stil werden vom Compiler überprüft. Casts im C-Stil sind keine und können zur Laufzeit fehlschlagen.

Außerdem können Casts im C ++ - Stil leicht gesucht werden, während es wirklich schwierig ist, nach Casts im C-Stil zu suchen.

Ein weiterer großer Vorteil ist, dass die 4 verschiedenen Casts im C ++ - Stil die Absicht des Programmierers klarer ausdrücken.

Beim Schreiben von C ++ würde ich so ziemlich immer die C ++ über dem C-Stil verwenden.

Tal
quelle
66
Die einzigen Casts, die zur Laufzeit fehlschlagen können, sind dynamic_casts.
R. Martinho Fernandes
11
C ++ reinterpret_cast <T> (U) kann zur Laufzeit genauso fehlschlagen wie C-Casts, und sie unterscheiden sich alle erheblich davon, wie dynamic_cast <T> (U) fehlschlägt.
Christopher Smith
19
˗1 normale C-Umwandlung (int)somethingkann nicht fehlschlagen - entweder Sie erhalten eine Umwandlung in int oder einen Compilerfehler.
Tomáš Zato - Wiedereinsetzung Monica
2
Können Sie erläutern, warum C ++ - Casts einfacher gesucht werden können als C-Casts?
Minh Tran
3
@MinhTran Für den C ++ - Stil können Sie in Ihren Quelldateien nach dem Schlüsselwort "cast" suchen. Aber was willst du mit den C-Casts machen?
Huangzonghao
176

Kurzum :

  1. static_cast<>() bietet Ihnen die Möglichkeit zur Überprüfung der Kompilierungszeit, C-Style-Besetzung nicht.
  2. static_cast<>() ist besser lesbar und kann überall in einem C ++ - Quellcode leicht entdeckt werden, C_Style Cast ist es nicht.
  3. Absichten werden mit C ++ Casts viel besser vermittelt.

Weitere Erläuterungen :

Die statische Umwandlung führt Konvertierungen zwischen kompatiblen Typen durch . Es ähnelt der Besetzung im C-Stil, ist jedoch restriktiver. Beispielsweise würde die Umwandlung im C-Stil einem ganzzahligen Zeiger erlauben, auf ein Zeichen zu zeigen.

char c = 10;       // 1 byte
int *p = (int*)&c; // 4 bytes

Da dies zu einem 4-Byte-Zeiger (ein Zeiger auf einen 4-Byte-Datentyp) führt, der auf 1 Byte des zugewiesenen Speichers zeigt, verursacht das Schreiben in diesen Zeiger entweder einen Laufzeitfehler oder überschreibt einen benachbarten Speicher.

*p = 5; // run-time error: stack corruption

Im Gegensatz zur Umwandlung im C-Stil kann der Compiler bei der statischen Umwandlung überprüfen, ob die Zeigertypen und Zeigerdatentypen kompatibel sind, sodass der Programmierer diese falsche Zeigerzuweisung während der Kompilierung abfangen kann.

int *q = static_cast<int*>(&c); // compile-time error

Sie können diese Seite auch auf weitere Erklärungen zu C ++ - Casts überprüfen: Klicken Sie hier

Brise
quelle
16
Ich denke, anstelle von "4-Byte-Zeiger" meinten Sie "Zeiger auf 4-Byte-Datentyp"
iheanyi
aber es erlaubt int q = static_cast <int> (c);
TonyParker
3
@ TonyParker Das liegt daran, dass an dieser Zeile nichts falsch ist.
Braden Best
15

Siehe Ein Vergleich der C ++ - Casting-Operatoren .

Die Verwendung derselben Syntax für eine Vielzahl unterschiedlicher Casting-Vorgänge kann jedoch die Absicht des Programmierers unklar machen.

Darüber hinaus kann es schwierig sein, einen bestimmten Cast-Typ in einer großen Codebasis zu finden.

Die Allgemeingültigkeit der Besetzung im C-Stil kann in Situationen, in denen lediglich eine einfache Konvertierung erforderlich ist, übertrieben sein. Die Möglichkeit, zwischen mehreren verschiedenen Casting-Operatoren mit unterschiedlichen Leistungsgraden zu wählen, kann verhindern, dass Programmierer versehentlich auf einen falschen Typ gießen.

Eugene Yokota
quelle
14
struct A {};
struct B : A {};
struct C {}; 

int main()
{
    A* a = new A;    

    int i = 10;

    a = (A*) (&i); // NO ERROR! FAIL!

    //a = static_cast<A*>(&i); ERROR! SMART!

    A* b = new B;

    B* b2 = static_cast<B*>(b); // NO ERROR! SMART!

    C* c = (C*)(b); // NO ERROR! FAIL!

    //C* c = static_cast<C*>(b); ERROR! SMART!
}
Rishi Khaneja
quelle
5
Könnten Sie bitte Ihre Antwort näher erläutern und etwas mehr Beschreibung der von Ihnen angebotenen Lösung hinzufügen?
Abarisone
1
Ich denke, die Antwort zeigt, dass "static_casts" nach Typkonvertierungen sucht, um sicherzustellen, dass sie sich auf gültigen Pfaden im Hierarchiediagramm befinden. In diesem speziellen Beispiel ist das Umwandeln von A * nach B * oder B * nach A * zulässig, da A und B einen Pfad im hierarchischen Diagramm bilden. C * befindet sich nicht auf dem Pfad, sodass static_cast einen Fehler bei der Kompilierung verursacht. Nebenbemerkung: Es kann erwähnenswert sein, dass das Umwandeln von A * nach B * je nach dem zugrunde liegenden Objekt zu NULL mit einem dynamic_cast zur Laufzeit führen kann.
Tommy Chen
7

Ein großartiger Beitrag, in dem verschiedene Besetzungen in C / C ++ erklärt werden und was die Besetzung im C-Stil wirklich bewirkt: https://anteru.net/blog/2007/12/18/200/index.html

C-Style-Casting unter Verwendung der (Typ-) Variablensyntax. Das Schlimmste, das jemals erfunden wurde. Dies versucht, die folgenden Casts in dieser Reihenfolge auszuführen: (siehe auch C ++ Standard, 5.4 expr.cast Absatz 5)

  1. const_cast
  2. static_cast
  3. static_cast gefolgt von const_cast
  4. reinterpret_cast
  5. reinterpret_cast gefolgt von const_cast
Ying Xiong
quelle
5

static_castprüft beim Kompilieren, ob die Konvertierung nicht zwischen offensichtlich inkompatiblen Typen erfolgt. Im Gegensatz dazu dynamic_castwird zur Laufzeit keine Überprüfung der Typkompatibilität durchgeführt. Auch die static_castKonvertierung ist nicht unbedingt sicher.

static_cast wird verwendet, um vom Zeiger zur Basisklasse zum Zeiger zur abgeleiteten Klasse oder zwischen nativen Typen wie enum to int oder float to int zu konvertieren.

Der Benutzer von static_cast muss sicherstellen, dass die Konvertierung sicher ist.

Die Besetzung im C-Stil führt weder zur Kompilierung noch zur Laufzeit eine Überprüfung durch.

kiriloff
quelle
3

Da es viele verschiedene Arten von Casting mit jeweils unterschiedlicher Semantik gibt, können Sie mit static_cast <> sagen: "Ich mache eine legale Konvertierung von einem Typ in einen anderen", z. B. von int in double. Eine einfache Besetzung im C-Stil kann viele Dinge bedeuten. Bist du Up / Down Casting? Interpretieren Sie einen Zeiger neu?

Doug T.
quelle