2012-04-08 11 views
2

Ich habe einen kleinen Zweifel in der virtuellen Tabelle, wann immer Compiler auf die virtuellen Funktionen in einer Klasse trifft, erstellt Vtable und legt virtuelle Funktionen Adresse da drüben. Ähnliches gilt für andere Klassen, die erben. Erzeugt es in jeder Klasse einen neuen Zeiger, der auf jede VTable zeigt? Wenn nicht, wie greift es auf die virtuelle Funktion zu, wenn die neue Instanz der abgeleiteten Klasse erstellt und der Basis-PTR zugewiesen wird?Wie Vtable von virtuellen Funktionen funktioniert

+0

mögliche Duplikate von [Virtual Table C++] (http://stackoverflow.com/questions/2173493/virtual-table-c) –

Antwort

1

Für jede Klasse mit virtuellen Funktionen wird eine VTable erstellt. Wenn dann ein Objekt einer Klasse mit einem lebensfähigen Konstruktor unter Verwendung eines Konstruktors erstellt wird, kopiert der Konstruktor die entsprechende vtable in das Objekt. Jedes Objekt hat also einen Zeiger auf seine vtable (oder im Falle der Mehrfachvererbung, wenn nötig, ein Orr für jede seiner vtables). Der Compiler weiß, wo sich die Vtable im Objekt befindet. Wenn also eine virtuelle Methode aufgerufen werden muss, gibt sie einen Bytecode aus, um die Vtable abzuschrecken, die entsprechende Methode zu suchen und zu ihrer Adresse zu springen. Im einfachen Fall der einfachen Vererbung beginnt eine untergeordnete Klasse mit einer Kopie der vtable der übergeordneten Klasse und erhält dann für jede virtuelle Methode in der untergeordneten Klasse einen überschriebenen Eintrag, der die Methode einer übergeordneten Klasse überschreibt. (Und es wird auch einen neuen Eintrag für jede virtuelle Funktion in dem Kind gekleidet, das tut nicht Überschreibung einer Elternklasse-Methode)

5

Jedes Mal, wenn Sie eine Klasse erstellen, die virtuellen Funktionen enthält, oder Sie stammen aus einer Klasse, enthält virtuelle Funktionen, der Compiler erstellt eine eindeutige VTABLE für diese Klasse.

Wenn Sie keine Funktion tun außer Kraft setzen, die virtuelle in der Basisklasse deklariert wurde, der Compiler verwendet die Adresse der Basisklasse Version in der abgeleiteten Klasse.

Dann platziert es die VPTR in der Klasse. Es gibt nur ein VPTR für jedes Objekt, wenn eine einfache Vererbung verwendet wird. Der VPTR muss initialisiert werden, um auf die Startadresse des entsprechenden VTABLE zu zeigen. (Dies geschieht in dem -Konstruktor.) Sobald das VPTR mit dem richtigen VTABLE initialisiert wird, "weiß" das Objekt in Effekt, welcher Typ es ist. Aber diese Selbsterkenntnis ist wertlos , es sei denn es wird an dem Punkt verwendet, an dem eine virtuelle Funktion aufgerufen wird. Wenn Sie eine virtuelle Funktion über eine Basisklassenadresse aufrufen (die Situation, wenn der Compiler nicht über alle erforderlichen Informationen für die frühe Bindung verfügt), passiert etwas Besonderes. Anstelle eines typischen Funktionsaufrufs, bei dem es sich einfach um eine Assemblersprache an einer bestimmten Adresse handelt, generiert der Compiler anderen Code, um den Funktionsaufruf auszuführen.

+0

Also, Sie wollen sagen wie. Nur ein VPTR zeigt während der Erstellung des Objekts auf eine bestimmte Tabelle und nicht während des Zuweisungsrechts. Aber es wird immer in der Basisklasse vorhanden sein. – Naruto

+0

Wie ich bereits sagte, erstellt der Compiler eine eindeutige VTABLE für eine Klasse und ihre abgeleitete Klasse. – IndieProgrammer

+0

Was ist mit dem VPTR für VTABLE ?, wie funktioniert es, wenn Sie die abgeleitete Klasse instanziieren und zu base ptr zuweisen? – Naruto

3

Immer wenn das Programm kompiliert wird, wird die virtuelle Tabelle für jede Klasse erstellt, was deutlich macht, dass Vtables pro Klassenbasis erstellt werden. Während der Laufzeit, wenn das Objekt erstellt wird, weist der Compiler dem Objekt vptr zu, das auf die virtuelle Tabelle für das Objekt der bestimmten Klasse verweist. Kurz gesagt, das vptr wird pro Objektbasis erstellt.