2012-01-19 5 views

risposta

9

È fortemente dipendente dall'implementazione, ma in genere si otterrà un oggetto vtable per classe che ha funzioni virtuali (classi senza funzioni virtuali o basi non ne hanno bisogno) e un vptr per oggetto di una classe con un vtable (indicando il vtable della classe).

Le cose diventano più complesse se si dispone di più ereditarietà e classi di base virtuali, che possono essere implementate in molti modi. Alcune implementazioni usano un'aggiunta vtable per ogni classe di base addizionale (così si finisce con un vtable per classe base per classe), mentre altri usano un singolo vtable con informazioni extra in esso. Ciò potrebbe comportare la necessità di più vptr per oggetto.

La parola chiave virtual in B è irrilevante - se la funzione è virtuale nella classe base, sarà virtuale nelle classi derivate a prescindere.

+0

ora se modifico il mio pgm come di seguito: rimuovo la parola chiave virtuale dalla classe derivata. Ora quanti vtables saranno creati? – CodeCodeCode

+2

@Pal - Nessuna differenza, la funzione è ancora virtuale. –

+0

@Bo Persson: la funzione è virtuale ma, ci sarà anche un vtable creato per la classe derivata? – CodeCodeCode

3

Si noti che questo è strettamente dipendente dall'implementazione.
Lo standard C++ non parla di vptr o vtable, il meccanismo virtuale è escluso come dettaglio di implementazione per i compilatori. Quindi, in pratica, i compilatori possono implementarlo senza utilizzare vptr o vtable. Tuttavia, quasi tutti i compilatori noti lo implementano utilizzando vptr e vtable.

luce di quanto sopra, per rispondere alla tua domanda:

Ogni classe avrà una propria tabella virtuale.
Mentre ogni oggetto ha il proprio puntatore virtuale.

+0

Grazie Als per la risposta, ora mi sono un po 'confuso. per favore spiegami se rimuovo la parola chiave virtuale dalla classe B (derivata) allora quanti vtables saranno creati? – CodeCodeCode

+0

@CodeCodeCode se rimuovi la parola chiave virtuale dalla classe B (derivata) allora quanti vtables verranno creati? la risposta rimane la stessa 2 per base e derivata. –

+0

@aloksave Ho letto da qualche parte che dato che una classe base ha una funzione virtuale avrà un vptr e lo stesso è ereditato dalla classe derivata ma punta alla classe derivata vtable. Potete aiutarci? –

7

Fondamentalmente, 2. Uno per class A, uno per class B (vftables) e 2 vfptrs, uno per a1 e uno per b1.

Tuttavia, questo non è obbligatorio, quindi non si può avere nessuno. (Di solito le implementazioni usano vftables, ma la sua non mandato.

Nota @R. Martinho Fernandes con le ottimizzazioni su, non avrete oggetti creati, in modo che nessun vfptrs.

+0

+1 per affermare effettivamente i numeri come la domanda posta –

12

Questo programma può essere ottimizzato per essere esattamente come questo:

int main(){} 

Quindi, "none" è una possibilità

+0

Voglio fare +1 per divertirti, ma ... –

+0

Non necessariamente, potresti avere 2 o 1000 (non è obbligatorio ottimizzarlo). Ma +1 per il pensiero :) –

+0

int main() {} è sufficiente per scrivere un programma C++. non c'è bisogno di altre linee di codice. :) – CodeCodeCode

2

tavolo Virual verrà creato solo se atleast 1 funzione virtuale è lì nella classe Base, che verrà ereditato alcun modo al. classi derivate.it non importa anche se rimuovi la parola chiave virtuale dalla classe derivata B perché stai già vivendo un divertimento virtuale() in A. Quindi il numero di tabelle virtuali sarà 2 (come base per classe) e il numero di virtual ptrs sarà anche 2, come base per oggetto.VTABLE per A --- v_ptr *, A :: fun()

& VTABLE per B --- V_ptr * (che è stato ereditato da A), B :: fun()/* B hanno accesso ad entrambi A :: fun & B's fun(), ma dato che abbiamo menzionato A :: fun() come virtuale la tabella virtuale di B è riempita con la versione più derivata della funzione, fun(), che non è altro che B :: fun(). spero che questo cancella ur dubbio

0

ci saranno 2 vtables, uno per classe a e uno per di classe B. E ci saranno 3 vptrs, uno in a1 e due in b1 (uno che punta a vtable di classe A e altro che punta a vtable di classe B).