Sagen wir, wir haben unter Programm:
%Vor% Meine Frage ist, wie viele vtables
und wie viele vptrs
erstellt werden, wenn wir dieses Programm ausführen?
Es hängt stark von der Implementierung ab, aber im Allgemeinen erhalten Sie ein vtable-Objekt pro Klasse mit virtuellen Funktionen (Klassen ohne virtuelle Funktionen oder Basen brauchen sie nicht) und ein vptr pro Objekt einer Klasse mit einer vtable (zeigt auf die Vtable der Klasse).
Die Dinge werden komplexer, wenn Sie mehrere Vererbungs- und virtuelle Basisklassen haben - was auf viele Arten implementiert werden kann. Einige Implementierungen verwenden eine zusätzliche vtable pro zusätzlicher Basisklasse (Sie erhalten also eine vtable pro Basisklasse pro Klasse), während andere eine einzelne vtable mit zusätzlichen Informationen verwenden. Dies kann dazu führen, dass mehrere vptrs pro Objekt benötigt werden.
Das Schlüsselwort virtual
in B ist irrelevant - wenn die Funktion in der Basisklasse virtuell ist, wird sie in den abgeleiteten Klassen unabhängig davon virtuell sein.
Dieses Programm kann genau wie dieses optimiert werden:
%Vor%Also, "keine" ist eine Möglichkeit.
Grundsätzlich 2. Eine für class A
, eine für class B
(vftables) und 2 vfptrs, eine für a1
und eine für b1
.
Dies ist jedoch nicht standardmäßig vorgeschrieben, Sie könnten also auch keine haben. (Normalerweise verwenden Implementierungen vftables, aber es ist nicht vorgeschrieben.
Hinweis @R. Martinho Fernandes mit Optimierungen auf, du wirst keine Objekte erstellt haben, also keine vfptrs
.
Beachten Sie, dass dies ausschließlich von der Implementierung abhängig ist.
C ++ Standard spricht nicht von vptr
oder vtable
, der virtuelle Mechanismus wird als Implementierungsdetail für Compiler weggelassen. In der Praxis können Compiler es also implementieren, ohne vptr
oder vtable
zu verwenden. Jedoch implementieren fast alle bekannten Compiler es mit vptr
und vtable
.
Angesichts der oben genannten, um Ihre Frage zu beantworten:
Jede Klasse wird ihre eigene virtuelle Tabelle haben.
Während jedes Objekt seinen eigenen virtuellen Zeiger hat.
Virualtabelle wird nur erstellt, wenn mindestens eine virtuelle Funktion in der Basisklasse vorhanden ist, die auf die abgeleiteten Klassen vererbt wird. Es spielt keine Rolle, auch wenn Sie das virtuelle Schlüsselwort aus der abgeleiteten Klasse B entfernen, weil Sie es bereits haben ein virtueller Spaß () in A. Also wird die Anzahl der virtuellen Tabellen 2 sein (wie pro Klasse) und die Anzahl der virtuellen Einheiten wird ebenfalls 2 sein, wie pro Objekt. VTABLE für A --- v_ptr *, A :: fun ()
& amp; VTABLE für B --- V_ptr * (das von A geerbt wurde), B :: fun () / * B haben Zugriff auf sowohl A :: fun & amp; B's fun (), aber da wir A :: fun () erwähnt haben, ist die virtuelle Tabelle von virtuellem B mit der am weitesten abgeleiteten Version der Funktion fun () gefüllt, die nichts anderes als B :: fun () ist Zweifel
Es wird 2 vtables
geben, eins für Klasse A und eins für Klasse B . Und es wird 3 vptrs
, eins in a1 und zwei in b1 geben (eins zeigt auf vtable
von Klasse A und anderes zeigt auf vtable
von Klasse B ).