2010-08-13 20 views
5

Meine Frage ist, unter Bezugnahme auf this question, die erklärt, wie virtuelle Funktionen bei Objekt Slicing arbeiten, die Basisklasse virtuelle Funktion aufrufen Ende und Wikipedia article, die den virtuellen Tabellen-Layout für eine abgeleitete Klasse für Code unten erklärtVirtuelle Funktionen Objekt Slicing

class A{ 

    public: 
    virtual void func(){ cout<<"\n In A:func";} 
    }; 

    class B:public A{ 

    public: 
    virtual void func(){ cout<<"\n In B:func";} 
    }; 

    main(){ 
    A *ptr1 = new B(); 

    A oA = *ptr1; 

    oA.func(); 
    } 




     DerviedClassObjectB: 
     +0: pointer to virtual method table of B 

     virtual method table of B: 
     +0: B::func 

Über Programmausgaben "In A :: func".

Aber wie ohne virtuelle Tabelle tut für Klasse B: Jetzt wird gespart Basisklasse A :: func endet A :: func

Antwort

13

„für Klasse Virtuelle Tabelle B“ nennen? Virtuelle Tabelle für Klasse B ist überhaupt nicht in oA.func() Aufruf beteiligt. Das Objekt hat den Typ A, was bedeutet, dass seine virtuelle Tabelle die der Klasse A ist.

Darüber hinaus werden die meisten Compiler den oA.func() Aufruf optimieren, so dass es keine virtuellen Tabellen überhaupt verwenden wird. Da der Typ zum Zeitpunkt der Kompilierung bekannt ist, kann der Aufruf oA.func() sofort an A::func ohne Verwendung virtueller Tabellen gerichtet werden.

11
A oA = *ptr1; 

Dies kopiert alle Elementvariablen in ein neues A-Objekt. Der Vtable-Zeiger ist keine normale Elementvariable und wird nicht kopiert. Daher werden alle nachfolgenden virtuellen Funktionen, die für dieses Objekt aufgerufen werden, so behandelt, als wären sie ein A-Objekt, weil es ein A-Objekt ist.