Typkonvertierungen und Klassenzeiger
static_cast-Operator
Wie zuvor im Kapitel Typkonvertierungen erwähnt, kann mittels des static_cast-Operators unter anderem ein void-Zeiger in einen beliebigen anderen Zeigertyp konvertiert werden.
Mithilfe des static_cast-Operators kann aber auch ein Basisklassenzeiger in einen Zeiger auf eine davon abgeleiteten Klasse konvertiert werden. Dies wird als downcasting bezeichnet. Wird versucht mittels static_cast einen Basisklassenzeiger auf eine nicht von der Basisklasse abgeleitete Klasse zu konvertieren, führt dies beim Übersetzen des Programms zu einem Fehler.
Außer zur Konvertierung von Zeigern kann static_cast ebenfalls zum Konvertieren von Referenzen eingesetzt werden.
// Basisklasse
class Base
{...} *pBase;
// Abgeleitete Klasse
class Sub: public Base
{...} subObj;
// Beliebige weiter Klasse
class Any
{...};
// Basis-Referenz auf abgeleitetes Objekt
Base& baseRef = subObj;
// Basisklassen Zeiger auf abgeleitete Klasse
Sub *pSub = static_cast<Sub*>(pBase);
// Aber das geht nicht!
Any *pAny = static_cast<Any*>(pBase);
// Basisklassen Referenz auf Referenz abgel. Klasse
Sub& refSub = static_cast<Sub&>(baseRef);
dynamic_cast-Operator
Der dynamic_cast-Operator dient ausschließlich zum Konvertieren von Zeigern und Referenz zwischen abgeleiteten Klassen. Er wird hauptsächlich eingesetzt, wenn ein Basisklassenzeiger auf einen Zeiger einer abgeleiteten Klasse konvertiert werden soll (downcasting). Diese Konvertierung lässt sich auch mittels des static_cast-Operators durchführen, aber der dynamic_cast-Operator bietet eine zusätzliche Funktionalität: Er überprüft zur Laufzeit, ob im Basisklassenzeiger auch ein Verweis auf die entsprechende Klasse enthalten ist.
// Basisklasse
class Base
{...};
// Abgeleitete Klasse
class Sub: public Base
{...};
// Definitionen
Base *pBase1 = new Sub;
Base *pBase2 = new Base;
Sub *pSub;
// Konvertierungen ok
pSub = dynamic_cast<Sub*>(pBase1);
// Konvertierung schlägt fehl, Ergebnis ist nullptr!
pSub = dynamic_cast<Sub*>(pBase2);
Die erste Konvertierung konvertiert den Basisklassenzeiger pBase1 in einen Sub-Zeiger. Da pBase auf ein Objekt vom Typ Sub verweist, liefert diese Konvertierung keinen Fehler zurück. Die zweite Konvertierung hingegen schlägt fehl. Hier wird der Basisklassenzeiger pBase2 in einen Sub-Zeiger konvertiert. Da in pBase2 ein Verweis auf ein Base-Objekt abgelegt ist, liefert der dynamic_cast-Operator hier als Ergebnis einen nullptr zurück. D.h., der dynamic_cast-Operator überprüft zur Laufzeit, ob die Konvertierung des Basisklassenzeigers typsicher durchgeführt werden kann.
Wird anstelle eines Zeigers eine Referenz mittels dynamic_cast konvertiert und die Konvertierung ist nicht zulässig, löst der dynamic_cast-Operator eine Ausnahme vom Typ bad_cast aus.
Der dynamic_cast--Operator arbeitet nur mit Zeiger auf polymorphe Klassen, d.h., die Klasse muss mindestens eine virtuelle Methode enthalten.