Ändert sich der vptr während der Zerstörung?

8

Ich habe diesen Artikel gelesen und es heißt "Beim Eintritt in den Basisklassen-Destruktor das Objekt wird zu einem Basisklassenobjekt, und alle Teile von C ++ - virtuelle Funktionen, Dynamic_casts usw. - behandeln es auf diese Weise. " Bedeutet das, dass sich der VPTR während der Zerstörung verändert hat? Wie ist das passiert?

    
pythonic metaphor 27.10.2011, 13:48
quelle

2 Antworten

9

In allen Implementierungen, die virtuelle Funktionstabellen (d. h. alle aktuellen C ++ - Implementierungen) verwenden, lautet die Antwort ja, die vptr ändert sich zu der des Typs des Destruktors, der gerade ausgeführt wird. Der Grund dafür ist, dass der Standard erfordert, dass der Typ des zu zerstörenden Objekts der Typ des Destruktors ist, der gerade ausgeführt wird.

Wenn Sie eine Hierarchie der drei Typen B, D, MD (Basis, abgeleitet, am meisten abgeleitet) haben und ein Objekt vom Typ MD instanziieren und zerstören, dann führen Sie während der Ausführung von MD::~MD() den Typ des Objekts is MD , aber wenn der implizite Aufruf an den Basisdestruktor ausgeführt wird, muss der Laufzeittyp des Objekts D sein. Dies wird durch Aktualisieren von vptr erreicht.

    
David Rodríguez - dribeas 27.10.2011, 13:55
quelle
6

Die pedantische C ++ Antwort lautet natürlich: "Der Standard sagt nichts über vtbls aus oder wie Polymorphismus implementiert ist."

Aber praktisch, ja. Das vtbl wird geändert, bevor der Rumpf des Destruktors der Basisklasse mit der Ausführung beginnt.

BEARBEITEN:

Hier habe ich MSVC10 verwendet, um zu sehen, dass dies für mich selbst passiert. Zuerst der Testcode:

%Vor%

Setzen Sie nun einen Haltepunkt an der öffnenden Klammer für Poly dtor.

Wenn Sie diesen Code ausführen, wenn er die öffnende Klammer unterbricht (kurz bevor der Body des Konstruktors ausgeführt wird), können Sie einen Blick auf den vptr werfen:

Sie können auch die Disassemblierung für Poly dtor:

anzeigen %Vor%

Geh über die nächste Zeile, in den Körper des Destruktors, und guck einen weiteren Blick auf den vptr:

Wenn wir jetzt DoTest im Rumpf des Destruktors aufrufen, wurde der vtbl bereits so geändert, dass er auf purecall_ zeigt, wodurch im Debugger ein Runtime Assertion-Fehler generiert wird:

    
John Dibling 27.10.2011 14:06
quelle

Tags und Links