void (** vt) () = * (void (***) ()) ptr; eine Hilfsvariable für die virtuelle Tabelle in C ++

8

Ich habe diese Technik im folgenden Link gefunden: Ссылка

und dort verwendet er eine Hilfsvariable

%Vor%

hilft bei der Anzeige der virtuellen Funktionstabelle.

Aber wenn ich es zu

ändere %Vor%

funktioniert nicht wie die vorherige.

Könnte mir bitte jemand erklären, was Magie hier spielt?

    
Alex 15.08.2013, 03:45
quelle

2 Antworten

3

Der virtuelle Tabellenzeiger in vielen C ++ - Implementierungen ist der erste sizeof(void (**)()) -Byte des Objekts. Wenn Sie diesen Zeiger dereferenzieren, erhalten Sie die Anfangsadresse der realen virtuellen Tabelle. Das ist die Bedeutung des Arbeitscodes.

Das cdecl -Programm könnte hier eine kleine Hilfe sein:

%Vor%

Der erste Code gibt den Zeiger auf Ihr Objekt als einen korrekt dereferenzierbaren Zeiger aus ( Zeiger auf Zeiger auf Funktion , void (***)() ) und dereferenziert ihn dann, um die Startadresse für das virtuelle Objekt zu ermitteln Tabelle mit dem Typ void (**)() ( Zeiger auf Zeiger auf Funktion ), der auf den Anfang der virtuellen Tabelle verweist, die den Typ void (*[])() ( Zeigerfeld zur Funktion hat ).

Bei der zweiten wird nur der Zeiger auf ein Objekt auf einen Zeiger auf einen Zeiger auf eine Funktion, die void zurückgibt, angewendet. Die in der Variablen vt gespeicherte Adresse ist nur die Adresse Ihres Objekts.

%Vor%

Also mit

%Vor%     
Antti Haapala 15.08.2013, 03:57
quelle
8

Lassen Sie uns ein typedef für Klarheit einführen.

%Vor%

Dann ist der erste Code

%Vor%

und der zweite

%Vor%

Das heißt, das erste sagt "behandle ptr als Zeiger auf ein Ding und gib mir, worauf es hinweist" und das zweite "behandle ptr als Ding".
Der Unterschied sollte offensichtlich sein.

Der Grund, warum überhaupt funktioniert, ist sowohl für den Visual C ++ - Compiler als auch für den Visual Studio-Debugger sehr spezifisch.

Wenn der Debugger nicht weiß, welcher Typ das Objekt wirklich ist, zeigt er an, was er weiß, nämlich dass es eine Instanz der Basisklasse ist, und er weiß nur, wie viele Einträge die vtable der Basisklasse hat.

(Sie haben hier einen entscheidenden Teil weggelassen, der darin besteht, die erwartete Anzahl von Tabelleneinträgen dem Element im Überwachungsfenster hinzuzufügen. Dadurch zeigt der Debugger diesen Speicher als ein Array von so vielen Elementen an, wie Sie sagen.)

Der Trick besteht also darin, einen Namen für die vtable zu erfinden und dem Debugger mitzuteilen, wie viele Elemente aus der Tabelle angezeigt werden sollen.

    
molbdnilo 15.08.2013 03:57
quelle

Tags und Links