2010-03-31 13 views
7

Który wirtualny stół będzie czystą funkcją wirtualną? W klasie bazowej lub klasie pochodnej?Gdzie jest czysta funkcja wirtualna znajdująca się w C++?

Na przykład, jak wygląda tabela wirtualna w każdej klasie?

class Base { 

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


class Derived: public Base{ 

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

} 
+0

pokrewne pytanie: http://stackoverflow.com/questions/2549618/ –

+0

Kto powiedział, że istnieje wirtualny stół? Standard nic o nich nie mówi i jako taki jest wytworem wyobraźni ludzi :-) Jeśli chcesz szczegółów implementacji specyficznych dla kompilatora, powinieneś wspomnieć o kompilatorze, którego używasz. –

Odpowiedz

15

produkuje plik layout.cpp.class. Zawartość layout.cpp.class pokaże następujące:

 
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) 

Zdejmowanie 'czystość' od f zmienia piątą linię do:

 
16 Base::f 
+0

Rzeczywiście:) –

+0

+1 Nice - pokonaj wszystkie zgadywanki –

1

Pozycja vtable będzie znajdować się w klasie bazowej.

Dlaczego? Ponieważ możesz mieć typ wskaźnika bazowego, który przechowuje adres obiektu typu pochodnego i nadal wywoływać metodę na zmiennej wskaźnika typu podstawowego.

Czysta wirtualny po prostu informuje kompilator, że typy pochodzące musi dostarczyć własną implementację, i że nie można polegać na realizacji klasy bazowej (jeśli jest jeszcze określony w klasie bazowej)

1

W obu rzeczywistości. Podstawowa klasa vtable będzie miała gniazdo dla czystej wirtualnej funkcji wskazujące na coś w rodzaju takiego jak pure_virtual_function_called(), który prawdopodobnie przerwałby program, podczas gdy klasa pochodna vtable będzie miała wskaźnik do faktycznej implementacji.

2

Każda klasa ma swój własny vtable. Wpis dla f w Base będzie NULL, a wpis w Derived będzie wskaźnikiem do kodu dla zaimplementowanej metody.

+1

Cóż, niezupełnie NULL. W VC++ wpis jest adresem funkcji CRT _purecall: http://thetweaker.wordpress.com/2010/06/03/on-_purecall-and-toheads-of-virtual-functions/ –

Powiązane problemy