2015-06-30 18 views
5

Ho letto su vtable e ho compreso il concetto per i puntatori di classe base che puntano a oggetti di classe base e derivati. Qualcuno può spiegare il caso di come vtable viene creato quando sia la classe base che la classe derivata sono oggetti e l'oggetto classe derivata è assegnato all'oggetto classe base. Caso 3 nell'esempio sottoFunzioni virtuali utilizzando oggetti di base e derivati ​​

#include <iostream> 
#include <exception> 
using namespace std; 


class Base 
{ 
public: 
    virtual void function1() { cout<<"Base - func1"<<endl; } 
    virtual void function2() { cout<<"Base - func2"<<endl; } 
}; 

class Derived1: public Base 
{ 
public: 
    virtual void function1() { cout<<"Derived1 - func1"<<endl; } 
}; 

class Derived2: public Base 
{ 
public: 
    virtual void function2() { cout<<"Derived2 - func2"<<endl; } 
}; 

int main() 
{ 
    // Case 1 
    Base* B1 = new Derived1(); 
    B1->function1(); 
    B1->function2(); 

    // Case 2 
    cout<<endl; 
    Base* B2 = new Derived2(); 
    B2->function1(); 
    B2->function2(); 

    // Case 3 
    cout<<endl; 
    Base B3; 
    Derived1 D1; 
    B3=D1; 
    B3.function1(); 
    B3.function2(); 
} 

uscita:

Derived1 - func1 
Base - func2 

Base - func1 
Derived2 - func2 

Base - func1 
Base - func2 
+1

Si sta tagliando per 'B3'. – Jarod42

+1

Basta sottolineare che nominare le classi D1, D2 e ​​quindi le variabili B1, B2, B3 possono confondere. Per lo meno usa la lettera minuscola per i nomi delle variabili per far capire che non sono nomi di classi. L'utilizzo di alcune convenzioni nel codice può aiutare te e chiunque legga. – aslg

+2

Non si dovrebbe usare la parola "vtable" a meno che non si parli di un'implementazione che utilizza specificamente la tecnica vtables per implementare le funzioni virtuali. Il linguaggio C++ non ha una nozione di vtables. –

risposta

2

B3=Derived; è un esempio di oggetto affettare ... solo i componenti di dati della classe di base vengono assegnati ai, e il puntatore vtable continua puntare alle funzioni della classe base.

È consigliabile evitare l'affettatura - può essere pericoloso (vedere this answer per una spiegazione). Ora si conosce il termine, troverete facilmente un sacco di lettura su un oggetto per affettare ....

0
Base B3; 
D1 Derived; 
B3=Derived; //There is called default assignment operator 

È definita così:

Base& operator=(const Base &objectToCopy) {...} 

L'operatore prende un argomento di tipo Base, quindi oggetto di tipo D1 viene trattato come oggetto di tipo Base. Significa che l'operatore di assegnazione vede solo i campi di Derived che si trovano nella classe Base. Tuttavia, il puntatore a vtable (che tecnicamente è un campo nascosto) non viene ancora copiato, perché crea sempre nel costruttore ed è associato in modo permanente al tipo di oggetto reale.

+1

L'operatore accetta un argomento di tipo 'const Base &', che * non * converte implicitamente in' Base'. La conversione avviene durante l'assegnazione, non durante la chiamata all'operatore. – EJP

+0

@EJP Mi dispiace. Ho espresso male. Ora è buono? –

+0

Non ha ancora niente a che fare con il tipo di argomento (che hai ancora erroneamente dichiarato). Ha a che fare con ciò che accade all'interno del metodo dell'operatore. – EJP