Downcasting mit dem ‘static_cast’ in C ++

Erwägen:

class base { base(); virtual void func(); } class derived : public base { derived(); void func(); void func_d(); int a; } main { base *b = new base(); sizeof(*b); // Gives 4. derived * d = static_cast(b); sizeof(*d); // Gives 8- means whole derived obj size..why? d->func_d(); } 

In dem obigen Code habe ich einen Basiszeiger, der auf das Basisobjekt verweist, auf den abgeleiteten classnzeiger reduziert. Ich frage mich, wie der abgeleitete pointers das gesamte abgeleitete classnobjekt hat. Ich kann die abgeleitete classnfunktion aufrufen (nur in der abgeleiteten class deklariert). Ich habe das Konzept hier nicht verstanden.

   

Wenn Sie static_cast , um ein Objekt in einen Typ zu static_cast , führt dies nicht zu undefiniertem Verhalten . Die Symptome von UB sind sehr unterschiedlich. Es gibt nichts, was sagt, UB kann nicht zulassen, dass die abgeleitete Member-function erfolgreich aufgerufen wird (aber es gibt nichts, was das garantiert, also zähle nicht darauf).

Hier ist die Regel für das Downcasting mit static_cast , gefunden in Abschnitt 5.2.9 ( [expr.static.cast] ) des C ++ Standards (C ++ 0x Formulierung):

Ein Prvalue vom Typ “pointer to cv1 B “, wobei B ein classntyp ist, kann in einen prvalue des Typs “pointer to cv2 Dkonvertiert werden , wobei D eine von B abgeleitete class ist, wenn eine gültige Standardkonvertierung von “pointer zu D “zu” pointers auf B “existiert, cv2 ist die gleiche cv-Qualifikation wie oder höher cv-Qualifikation als, cv1 , und B ist weder eine virtuelle Basisklasse von D noch eine Basisklasse einer virtuellen Basisklasse von D . Der Nullzeigerwert wird in den Nullzeigerwert des Zieltyps konvertiert. Wenn der prvalue vom Typ “pointers auf cv1 B ” auf ein B verweist, das eigentlich ein Unterobjekt eines Objekts vom Typ D , zeigt der resultierende pointers auf das umschließende Objekt vom Typ D Andernfalls ist das Ergebnis der Besetzung undefiniert.

Der einzige Cast, der die Laufzeitprüfung durchführt, ist dynamic_cast<>() . Wenn es eine Möglichkeit gibt, dass ein Cast zur Laufzeit nicht funktioniert, sollte dieser Cast verwendet werden.

Das Casting von leaf-> root (up casting) static_cast<>() funktioniert static_cast<>() .
Das Casting von root-> leaf (down casting) ist jedoch gefährlich und sollte (meiner Meinung nach) immer mit dynamic_cast<>() da Abhängigkeiten von Laufzeit-Informationen bestehen. Die Kosten sind gering, aber immer die Sicherheit wert.

sizeof existiert zur Kompilierzeit. Es weiß weder, noch ist es wichtig, dass Ihr Basisobjekt zur Laufzeit nicht auf ein derived Objekt zeigt. Sie versuchen, das Verhalten der Kompilierungszeit mit einer Laufzeitvariablen zu beeinflussen, was grundsätzlich unmöglich ist.