Axel Rogat
Objektorientiertes Programmieren mit C++ und JAVA
 
4.1: Lvalues Kapitel 4 5.1: Anweisungen 
 
  4.12 Typumwandlungen  
 

An diversen Stellen in einem Programm werden kommentarlos implizite Typumwandlungen durchgeführt, die meistens erwünscht sind, manchmal auch nicht (wir sehen später, wie man das bei eigenen Typen mit dem Schlüsselwort explicit verhindern kann).

Andererseits treffen oft unterschiedliche Typen in Ausdrücken oder Zuweisungen so aufeinander, daß der Compiler die gewünschte Interpretation nicht erraten kann. Dann kann der Programmierer explizite Typumwandlungen einsetzen.

4.12.1 Standardumwandlungen

Sie werden vom Compiler in Zuweisungen (auch in der Initialisierung und bei Funktionsargumenten) und innerhalb von Ausdrücken automatisch angewandt. Dazu gehören folgende Erscheinungen:

4.12.2 Explizite Typumwandlungen

Der Operator für eine explizite Typumwandlung wird auch als Cast bezeichnet (und der Vorgang als Casting).

Typumwandlungen, deren Art erst zur Laufzeit bestimmt wird, heißen dynamische Typumwandlungen und sind (für "verwandte" Klassen) mit dem Operator dynamic_cast möglich, der (viel) später besprochen wird.

Hier wollen wir uns nur mit statischen Typumwandlungen beschäftigen, d.h. solchen, die zur Übersetzungszeit festgelegt werden.

Die C-typischen Casts mit () sind in C++ natürlich immer noch erlaubt, es werden aber darüber hinaus speziellere Operatoren mit neuen Schlüsselwörtern zur Verfügung gestellt.

static_cast:

Das ist der "Ersatz" für die normalen Casts aus C.

Mit static_cast<T>(a) kann ein Ausdruck a vom Typ A in den Typ T umgewandelt werden. Das ist nur in speziellen Fällen erlaubt, nämlich:

  • wenn A implizit nach T umgewandelt werden kann (dann ist der cast also eigentlich überflüssig)

  • wenn T implizit nach A umgewandelt werden kann (das ist hauptsächlich für Zeigertypen gedacht, sonst kann es zu Genauigkeitsverlusten kommen)

  • wenn T ein enum-Typ ist und a ein ganzzahliger Wert, der im Wertebereich von T liegt (der Compiler braucht aber leider keine entsprechende Überprüfung zu generieren!)

  • wenn T und A Zeigertypen voneinander abgeleiteter Klassen sind (dazu später)

Das const-Verhalten sollte so nicht umgecastet werden, im zweiten Fall ist es sogar verboten. Dazu gibt es den nächsten Operator.

Außer im letzten Fall kann so nicht in Referenztypen umgewandelt werden, so daß man keine Lvalues als Ergebnis erhält.

const_cast:

Sehr selten ist es sinnvoll, das Konstantsein eines Objekts zu ignorieren.

Bei const_cast<T>(a) dürfen sich die Typen A von a und T nur durch const-Zusätze unterscheiden. So ist ein beliebiges Entfernen oder Hinzufügen von consts möglich.

Auch hier ergibt sich allerdings kein Lvalue, dazu dient der zusätzlich mögliche Referenz-Cast const_cast<T&>(a).

reinterpret_cast:

Mit reinterpret_cast<T>(a) wird die Typüberprüfung von C++ ganz ausgeschaltet. Zeiger können als ganze Zahlen interpretiert werden und umgekehrt, jeder Zeigertyp kann in jeden anderen konvertiert werden. Durch beliebige Uminterpretation der physikalischen Darstellung der Typen kann man so viel Unsinn anstellen. Nur das const-Verhalten kann man so nicht ändern.

()-Schreibweise:

Wenn einer der drei oben aufgeführten Casts von a in den Typ T möglich ist, kann man auch einfach T(a) ("funktional") oder (T)a (alter C-Stil) schreiben.

Bei der funktionalen Schreibweise muß T natürlich durch einen Identifier oder ein Schlüsselwort beschreibbar sein, ansonsten ist ein typedef-Umweg nötig. Der Lesbarkeit und Eindeutigkeit wegen sollte man aber außer in einfachen, offensichtlichen Fällen lieber die Schreibweise mit den Cast-Schlüsselwörtern benutzen.

 
4.1: Lvalues Startseite 5.1: Anweisungen 
 

© 1998 Axel Rogat