Domanda

Ho letto un sacco di gente che scrive "una tabella virtuale esiste per una classe che ha una funzione virtuale dichiarato in esso".

La mia domanda è, fa esiste un vtable solo per una classe che ha una funzione virtuale o lo fa esistere anche per le classi derivate da quella classe.

es

class Base{
    public:
        virtual void print(){cout<<"Base Print\n";}
};
class Derived:public Base{
    public:
        void print(){cout<<"Derived print\n";}
};

//From main.cpp 
Base* b = new Derived;
b->print();

Domanda: Se non ci fosse stato alcun vtable per la classe derivata allora l'uscita non sarebbe stato "print derivata". Quindi IMO esiste una vtable per qualsiasi classe che ha funzione virtuale dichiarata e anche in classi che ereditano da quella classe. È corretto?

È stato utile?

Soluzione

Per quanto riguarda la funzionalità solo virtuale-specifica funzione è considerato, in un approccio tradizionale alla realizzazione vtable classe derivata avrebbe bisogno di una versione separata vtable se e solo se che sostituzioni classe derivata almeno uno funzione virtuale. Nel tuo esempio, Derived sostituisce la funzione print virtuale. Poiché Derived ha la sua versione del print, la voce corrispondente Derived vtable è diverso da quello in Base vtable. Questo sarebbe normalmente necessaria una vtable separato per Derived.

Se Derived non ignorare nulla, formalmente ancora sarebbe una classe polimorfica separato, ma al fine di rendere le sue funzioni virtuali funzionano correttamente avremmo potuto semplicemente riutilizzato vtable Base per Derived pure. Quindi, tecnicamente non ci sarebbe alcun bisogno di un vtable separato per Derived.

Tuttavia, in implementazioni pratiche, la struttura dei dati che di solito si riferiscono a come "vtable", spesso contiene alcune informazioni di classe-specifica supplementare pure. Tale informazione in più è così di classe specifica che la maggior parte del tempo diventa impossibile VTables condivisione tra diverse classi di gerarchia, anche se usano lo stesso insieme di funzioni virtuali. Ad esempio, in alcune implementazioni puntatore vtable memorizzato in ogni punto oggetto polimorfici a struttura dati che memorizza anche i cosiddetti "informazioni RTTI" sulla classe. Per questo motivo, nella maggior parte (se non tutti) implementazioni pratiche ogni classe polimorfica ottiene il proprio vtable, anche se i puntatori a funzione virtuali memorizzati in tali tabelle capita di essere lo stesso.

Altri suggerimenti

Sì, la vostra comprensione è corretta. Ogni classe che ha una base con tutte le funzioni virtuali ha un vtable.

Sì, è vero. In realtà, defintion data della base:

class derived:public base{
public:
 void print(){cout<<"derived print\n";}
};

è del tutto equivalente a:

class derived:public base{
public:
 virtual void print(){cout<<"derived print\n";}
};

... perché già definito di stampa come virtuale in città.

mi piacerebbe auguro il compilatore imporrebbe che ...

Sì, è vero. Una classe eredita tutti i membri di dati dalla sua classe di base, tra cui la vtable. Tuttavia, le voci vtable sono regolati di conseguenza (per esempio se la classe sostituisce un metodo virtuale classe base, la voce corrispondente nel punto mosto vtable alla propria attuazione).

Ma tenere a mente che il concetto di un 'vtable' è una pratica comune utilizzata da vitually ogni compilatore, ma non è obbligatoria né standardizzato.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top