2010-03-31 6 views
7

Welche virtuelle Tabelle wird reine virtuelle Funktion sein? In der Basisklasse oder abgeleiteten Klasse?Wo befindet sich reine virtuelle Funktion in C++?

Zum Beispiel, wie sieht die virtuelle Tabelle in jeder Klasse aus?

class Base { 

    virtual void f() =0; 
    virtual void g(); 
} 


class Derived: public Base{ 

    virtual void f(); 
    virtual void g(); 

} 
+0

Verwandte Frage: http://stackoverflow.com/questions/2549618/ –

+0

Wer sagt, dass es eine virtuelle Tabelle gibt? Der Standard sagt nichts über sie aus und als solche sind sie ein Produkt der Phantasie der Leute :-) Wenn Sie compilerspezifische Implementierungsdetails wollen, müssen Sie den Compiler erwähnen, den Sie benutzen. –

Antwort

15

g++ -fdump-class-hierarchy layout.cpp erzeugt eine Datei layout.cpp.class. Der Gehalt an layout.cpp.class zeigt folgende:

 
Vtable for Base 
Base::_ZTV4Base: 4u entries 
0  (int (*)(...))0 
8  (int (*)(...))(& _ZTI4Base) 
16 __cxa_pure_virtual 
24 Base::g 

Class Base 
    size=8 align=8 
    base size=8 base align=8 
Base (0x7ff893479af0) 0 nearly-empty 
    vptr=((& Base::_ZTV4Base) + 16u) 

Vtable for Derived 
Derived::_ZTV7Derived: 4u entries 
0  (int (*)(...))0 
8  (int (*)(...))(& _ZTI7Derived) 
16 Derived::f 
24 Derived::g 

Class Derived 
    size=8 align=8 
    base size=8 base align=8 
Derived (0x7ff893479d90) 0 nearly-empty 
    vptr=((& Derived::_ZTV7Derived) + 16u) 
    Base (0x7ff893479e00) 0 nearly-empty 
     primary-for Derived (0x7ff893479d90) 

die 'Reinheit' Entfernen von f die fünfte Zeile ändert sich zu:

 
16 Base::f 
+0

Coole Sachen in der Tat:) –

+0

+1 Schön - schlagen Sie alle Ratespiele –

1

Der Vtable-Eintrag befindet sich in der Basisklasse.

Warum? Weil Sie einen Basis-Zeigertyp haben können, der die Adresse eines abgeleiteten Typobjekts enthält und die Methode dennoch für die Zeigervariable des Basistyps aufruft.

rein virtuelle einfach teilt den Compiler mit, dass die abgeleiteten Typen ihre eigene Implementierung zur Verfügung stellen müssen, und sie können nicht auf der Basisklasse Implementierung verlassen (wenn man auch in der Basisklasse angegeben)

1

In beide tatsächlich. Die Basisklasse vtable hat einen Slot für die reine virtuelle Funktion, die auf etwas wie pure_virtual_function_called() Stub verweist, das das Programm wahrscheinlich abbrechen würde, während die abgeleitete Klasse vtable einen Zeiger auf die tatsächliche Implementierung haben wird.

2

Jede Klasse hat ihre eigene vtable. Der Eintrag für f in Base wird NULL sein, und der Eintrag in Derived wird ein Zeiger auf den Code für die implementierte Methode sein.

+1

Nun, nicht wirklich NULL. In VC++ ist der Eintrag die Adresse der CRT-Funktion _purecall: http://thetweaker.wordpress.com/2010/06/03/on-purecall-and-the-overheads-of-virtual-functions/ –