kaiserludi hat geschrieben:Ist einer der beiden Casts aus irgendeinem Grund zu bevorzugen oder ist es reine Geschmackssache, welchen von den beiden man in dem Fall statt dem ebenfalls möglichen C-Cast nimmst?
Afaik gibt es da keinen Unterschied. Aber das gilt wirklich
nur für
void * (und vielleicht für den artverwandten
char *; habe die Paragraphen nicht griffbereit).
Falls du den Unterschied zwischen
reinterpret_cast und
static_cast wissen möchtest:
reinterpret_cast gibt dieselbe Stelle im Speicher aus, die reingegeben wurde. Und das ist, auch, wenn es kontraintuitiv klingt, oft unerwünscht …:
Erbt beispielsweise eine Klasse
Derived von zwei Klassen
Base1 und
Base2, dann wird das von vielen Compilern
so realisiert, dass die Klassen gemäß ihrer Vererbungshierarchie im Speicher liegen – erst eine komplette Instanz von
Base1 mitsamt Virtual Function Table / Type Information und dahinter allen ihren Attributen, dann dasselbe für
Base2 und schließlich die Attribute, die
Derived der Hierarchie hinzufügt. Die Funktionstabellen und Typinformationen sowohl vom
Base1- als auch vom
Base2-Teil werden mit den Funktionstabellen von
Derived überschrieben (jedoch erst, nachdem Ds K’tor fertig ist!).
Übergibst du nun eine Instanz von
Derived an eine Funktion, die
Base2 erwartet, geschieht die Magie: Die Funktion bekommt nicht die Adresse des kompletten
Base1-Base2-Derived-Blocks, sondern die des
Base2-Abschnitts der Instanz.
Ein polymorpher Typ ändert also unter Umständen seine Speicherposition, wenn man ihn zu einer seiner Basen zurückkonvertiert. Umgekehrt ändert ein Objekt möglicherweise seine Position, wenn man es zu einer ableitenden Klasse konvertiert.
Und da ist der Unterschied zwischen
static_cast und
reinterpret_cast:
static_cast zieht das in Betracht und gibt einen Zeiger auf das gültige Objekt der Basisklasse oder abgeleiteten Klasse zurück;
reinterpret_cast spuckt einfach denselben Zeiger mit anderem Typ aus und treibt dich damit wahrscheinlich früher oder später in die Hölle. (
dynamic_cast verhält sich wie
static_cast, nur, dass es durch die Funktionstabellen und Typinformationen sicherstellt, dass die Konvertierung gültig ist. Dadurch steigt aber übrigens auch seine Laufzeit von
O(1) auf
O(Vererbungstiefe zwischen den Klassen).)