In der Programmiersprache C++ ermöglicht die Typumwandlung es, dem Compiler explizit anzugeben, wie ein Objekt von einem Typ in einen anderen umgewandelt werden soll. In früheren Versionen von C++ (C++98) wurde dafür der C-style cast ((int)x) verwendet. Diese Vorgehensweise ist jedoch implizit und führt oft zu Fehlern, da der Compiler die Korrektheit oder Sicherheit der Umwandlung nicht überprüfen kann. Um die Sicherheit zu erhöhen, wurden spezielle Typumwandlungsoperatoren eingeführt, unter denen static_cast eine wichtige Rolle spielt.
Historie der Frage:
Vor der Einführung des Schlüsselworts static_cast hatten die Entwickler oft mit Fehlern aufgrund impliziter Umwandlungen zu kämpfen. Mit der Einführung von static_cast in C++98 wurde es möglich, verschiedene Absichten explizit zu unterscheiden und zu garantieren, dass die Umwandlung nur dort erfolgt, wo es logisch ist, zur Kompilierzeit.
Problem:
Es ist oft erforderlich, kompatible Typen (z. B. numerische Werte oder Zeiger auf verknüpfte Klassen) sicher und transparent umzuwandeln. Die standardmäßige Typumwandlung im C-Stil vermischt implizit vom Compiler überprüfbare und potenziell gefährliche Umwandlungen.
Lösung:
static_cast ist für die explizite, aber statisch überprüfbare Umwandlung kompatibler Typen gedacht. Es ist sicherer als die gewöhnliche C-Stil Umwandlung und erlaubt es nicht, völlig inkompatible Typen zur Kompilierzeit umzuwandeln.
Beispielcode:
class Base { }; class Derived : public Base { }; Base* b = new Derived(); Derived* d1 = static_cast<Derived*>(b); // korrekt, wenn b tatsächlich auf Derived zeigt int x = 10; double y = static_cast<double>(x); // funktioniert
Wichtige Merkmale:
dynamic_cast)Kann man static_cast für die Umwandlung zwischen völlig unverbundenen Typen verwenden, z. B. int und double**?**
Nein, der Compiler wird es nicht erlauben, eine solche Umwandlung ohne explizite Zwischenumwandlung über void* durchzuführen, da die Typen nicht direkt verbunden sind. Zum Beispiel:
int* p1; double* p2 = static_cast<double*>(p1); // Kompilierungsfehler
Kann man static_cast für eine sichere "Abwärts"-Umwandlung von einer Basisklasse in eine abgeleitete verwenden? Was geschieht, wenn der Zeiger nicht auf ein Objekt des abgeleiteten Typs verweist?
static_cast kann eine solche Umwandlung durchführen, überprüft jedoch nicht den tatsächlichen Typ zur Laufzeit. Wenn der Basisszeiger nicht auf ein Objekt der gewünschten abgeleiteten Klasse zeigt, führt dies zu undefiniertem Verhalten:
Base* base = new Base; Derived* wrong = static_cast<Derived*>(base); // UB! Typ ist falsch
Wie verhält sich static_cast bei privater Vererbung?
static_cast erlaubt es nicht, einen Zeiger oder eine Referenz auf eine Basisklasse durch private oder geschützte Vererbung außerhalb der abgeleiteten Klasse oder ihrer Freunde in eine abgeleitete Klasse umzuwandeln — es tritt ein Kompilierungsfehler auf.
Ein Programmierer verwendet gedankenlos static_cast zur Umwandlung beliebiger Zeiger auf eine Basisklasse in eine abgeleitete, ohne den tatsächlichen zugrunde liegenden Typ zu überprüfen (z. B. zur Geschwindigkeitsoptimierung).
Vorteile:
Nachteile:
Die Verwendung von static_cast nur nach Überprüfung des Objekttyps mithilfe zusätzlicher Metadaten oder Designs (oder für sichere Umwandlungen zwischen numerischen Typen).
Vorteile:
Nachteile: