2012-06-07 13 views
5

Come ho capito, l'ubicazione della tabella del puntatore di funzione virtual in un oggetto dipende dal compilatore.
Ci sono dei pro/contro nel posizionare questo puntatore all'inizio dell'oggetto vs alla fine o viceversa?posizione del puntatore della tabella di funzione virtuale nell'oggetto

+0

possibile duplicato di [Recupero di vptr (puntatore alla tabella virtuale aka VTABLE) dall'utilità Objdump?] (Http://stackoverflow.com/questions/10549311/retrieving-vptrpointer-to-virtual-table-aka-vtablefrom- the-objdump-utility) – iammilind

risposta

7

La semplice esistenza di una tabella di funzione virtuale dipende dal compilatore (ma tutti i compilatori lo fanno) e la posizione non è obbligatoria neanche ... In tutti i compilatori di cui Conosco i dettagli, il vptr è memorizzato all'inizio dell'oggetto. Il motivo è che fornisce una posizione uniforme. Si consideri una gerarchia di classi:

struct base { 
    T data; 
    virtual void f(); 
}; 
struct derived : base { 
    T1 data; 
    virtual void g(); 
}; 

Se il vptr è stato memorizzato alla fine dell'oggetto, allora sarebbe dopo sizeof(T) byte per un oggetto di tipo completo base. Ora quando si ha un oggetto di tipo completo derived, il layout dell'oggetto secondario base deve essere compatibile con il layout di un oggetto base completo, pertanto lo deve essere ancora sizeof(T) byte all'interno dell'oggetto, che sarebbe da qualche parte nel al centro dell'oggetto derived (sizeof(T) dall'inizio, sizeof(T1) prima della fine). Quindi non sarebbe più allo fine dell'oggetto.

Inoltre, dato un puntatore this, una chiamata virtuale richiede un'indiretto attraverso il vtable, che sostanzialmente è la dereferenziazione vptr, aggiungendo un offset e saltare alla posizione di memoria memorizzate. Se il vptr è stato memorizzato alla fine dell'oggetto, per ogni chiamata virtuale ci sarà un'ulteriore aggiunta a this prima di delegare il vptr.

+0

In teoria si potrebbe avere sia vptr sia alla fine del subobject della classe base sia dell'oggetto completo. Avrebbe senso: avere il vptr 'Derivato' per le funzioni virtuali che non appaiono in' Base'. Ma l'overhead per oggetto non è così carino. – MSalters

+0

Grande spiegazione !!! –

4

Sì, dipende completamente dall'implementazione.
Per una gerarchia di ereditarietà semplice si trova all'inizio dell'oggetto ma per una gerarchia complessa non lo sarà.
In ogni caso, qualsiasi codice sorgente che scrivi non dovrebbe fare affidamento su dove si trova, infatti qualsiasi codice che scrivi non dovrebbe fare affidamento sull'esistenza di una tabella virtuale o di un puntatore di una tabella virtuale.
Lo standard C++ non richiede che il dispatch virtuale venga implementato tramite la tabella virtuale e il puntatore, un'implementazione è libera di implementarlo utilizzando un altro metodo di implementazione, tuttavia tutti i compilatori mainstream implementano questo meccanismo tramite il puntatore del tavolo il punto importante da notare è che può differire nell'implementazione esatta di dove si trova il puntatore, ecc.

Problemi correlati