static_cast, dynamic_cast, const_cast, reinterpret_cast: Wann was verwenden?

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einleitung: Warum C++ keine Fehler bei Typumwandlungen verzeiht?



Hallo, Freund! Wenn du jemals in C++ programmiert hast – bist du bestimmt schon auf die Situation gestoßen, dass der Compiler sich über Typenkonflikte beschwert. Und dann erinnerst du dich wahrscheinlich an den guten alten C-Style-Cast: (int)x. Funktioniert es? Ja. Ist es sicher? Nein. Professionell? Noch weniger.



In C++ gibt es vier eingebaute Cast-Operatoren, und jeder löst seine eigene Aufgabe: static_cast, dynamic_cast, const_cast und reinterpret_cast. Sie richtig zu verwenden bedeutet, Code zu schreiben, der nicht nur funktioniert, sondern auch für andere Entwickler verständlich ist. Und außerdem – nicht zur Laufzeit mit mysteriösen Fehlern abstürzt.



In diesem Tutorial werden wir jeden Cast anhand von realen Beispielen analysieren, verstehen, wann man welchen anwendet und wann man besser gar nicht castet. Los geht's!



static_cast: Dein zuverlässiger Freund für gewöhnliche Umwandlungen



static_cast ist der beliebteste und sicherste Cast. Er wird für explizite Umwandlungen zwischen verwandten Typen verwendet: numerische Typen, Zeiger nach oben/unten in der Vererbungshierarchie (ohne Laufzeitprüfung), Aufzählungen in Ganzzahlen und umgekehrt.



Wann static_cast verwenden?

  • Umwandlung von int in double (und umgekehrt).
  • Umwandlung von Zeigern innerhalb einer Klassenhierarchie (Upcast – sicher, Downcast – man muss sicher sein).
  • Umwandlung von void* in einen bestimmten Typ.
  • Aufruf von expliziten Konstruktoren oder Umwandlungsoperatoren.


Beispiel:

double pi = 3.14159;int approx = static_cast<int>(pi); // 3

class Base { public: virtual ~Base() = default; };class Derived : public Base { public: void foo() {} };

Base* b = new Derived;Derived* d = static_cast<Derived*>(b); // OK, aber ohne Prüfungd->foo();delete b;


Wichtig: static_cast führt keine Laufzeit-Typüberprüfung durch. Wenn du sicher bist, dass das Objekt wirklich von diesem Typ ist – verwende ihn. Wenn nicht – schau dir dynamic_cast an.



dynamic_cast: Sicherer Downcast mit Prüfung



dynamic_cast ist der einzige Cast, der nur mit polymorphen Klassen funktioniert (es muss mindestens eine virtuelle Funktion vorhanden sein). Er prüft zur Laufzeit, ob der Zeiger/Referenz sicher umgewandelt werden kann. Wenn nicht – gibt er nullptr (für Zeiger) zurück oder wirft std::bad_cast (für Referenzen).



Wann dynamic_cast verwenden?

  • Wenn du nicht sicher bist, dass das Objekt wirklich vom abgeleiteten Typ ist.
  • Bei der Arbeit mit heterogenen Containern (z. B. vector aus Base*).
  • In Entwurfsmustern (z. B. Visitor).


Beispiel:

class Base { public: virtual ~Base() = default; };class Derived : public Base { public: void specific() {} };class Other : public Base {};

vector<Base*> objects = {new Derived, new Other, new Derived};

for (Base* obj : objects) { Derived* d = dynamic_cast<Derived*>(obj); if (d) { d->specific(); // nur für Derived sicher }}


Nachteil: dynamic_cast ist langsamer als static_cast, da es RTTI (Run-Time Type Information) benötigt. Verwende es nicht übermäßig in leistungskritischen Bereichen.



const_cast: Wenn man die Konstanz aufheben muss (aber vorsichtig!)



const_cast ist der einzige Cast, der cv-Qualifizierer (const, volatile) entfernen (oder hinzufügen) kann. Klingt cool, aber in der Praxis wird er selten und nur in Ausnahmefällen verwendet.



Wozu wird er überhaupt benötigt? Manchmal erhältst du eine konstante Referenz auf ein Objekt, musst aber eine alte Funktion aufrufen, die nicht als const markiert ist, obwohl sie das Objekt nicht ändert. Oder bei der Arbeit mit C-Bibliotheken.



Beispiel (korrekt):

void printInt(const int* p) {    // alt                

Blogs

Buchempfehlungen