So ist es unmöglich, mit static_cast
mit virtueller Vererbung niedergeschlagenen, aber wie ist es möglich, die folgende upcast zu tun:Wie kann static_cast mit virtueller Vererbung verwendet werden?
class Base {...};
class Derived : public virtual Base {...};
...
Derived *d = new Derived();
Base *b = static_cast<Base*>(d);
Speicherlayout des Objekts:
[ derived part | base part ]
Ich weiß, dass Upcasting betrachtet "Sicher", aber wie kann der Compiler den Offset zum Basisunterobjekt zur Kompilierungszeit kennen, wenn die Vererbung virtuell ist? Verwendet die static_cast
die ?
Dies ist besonders verwirrend, wenn wir so etwas wie diese haben (beachten Sie, dass es nicht virtuell ist):
class Third : public Derived {...};
...
Derived *d = new Third(); // non-virtual upcast, no offset will be added
Base *b = static_cast<Base*>(d);
Dieses Mal habe ich die gleiche static_cast
Linie verwendet, aber der Offset zum Base
Unterobjekt ist anders!
Speicherlayout des Objekts:
[ derived part | third part | base part ]
Wie kann es bei der Kompilierung festgelegt werden, wenn es auf dem tatsächlichen dynamischen Typ des Objekts abhängt d
Punkte?
Das ist normalerweise der Fall von dem, was ich weiß, dass die Offsets in der VTable gespeichert sind. Dies beantwortet jedoch nicht die Frage, wie es zur Kompilierzeit statisch gemacht wird. Wenn Sie sich die beiden Fälle ansehen, die ich zur Verfügung gestellt habe, stellt sich die Frage, welche vtable den richtigen Offset hat. Welche Version sollte der Compiler betrachten, die Vtable von Derived oder die Vtable von Third? Offensichtlich sind die 2 Offsets in den VTables unterschiedlich, und die Auswahl der richtigen Vtable hängt von dem Laufzeittyp d's ab. Deshalb kann ich nicht verstehen, wie es statisch gemacht wird. –
Das "statische" in 'static_cast' bedeutet nicht, dass es zur Kompilierzeit fertig ist! Es bedeutet lediglich, dass der Compiler während der Kompilierung statisch herausfinden kann, wo die Informationen zu finden sind: Er weiß zum Beispiel, wo der Offset in der V-Tabelle nachzuschauen ist oder wo der eingebettete Zeiger auf die Basis liegt (abhängig von der virtuellen Vererbung) ist implementiert). Es wird nicht nach einer Übereinstimmung einer Klasse in der V-Tabelle suchen, wie dies bei 'dynamic_cast' der Fall ist. –
Sie sagen also, dass static_cast einen dynamischen Aspekt hat, wie ich sehe. Warum kann static_cast aufgrund dieser Logik keine Downcasting-Funktion für virtuelle Vererbung verwenden? –