2012-01-19 14 views
35

Una volta, ero certo che non si potesse fare questo, ma l'altro giorno stavo giocando con un po 'di codice e sembrava compilare e lavorare. Voglio solo verificare che non sto solo diventando fortunato. Una classe template può avere una funzione virtuale pura - che suppongo significherebbe anche solo semplici metodi virtuali sarebbe valida anche per il distruttore?I metodi virtuali puri sono consentiti all'interno di una classe template?

template <typename WordType> class DataSource 
{ 
public: 
    DataSource(); 
    DataSource(DataSource const& other); 
    virtual ~DataSource(); 

    virtual void Put(
     WordType const* const data, 
     unsigned int const wordCount) = 0; 
} 

ho provato a guardare in su in linea e tutto quello che ho potuto trovare è che non si può avere un metodo virtuale (puro o altro) in una classe normale, come ad esempio questo:

class DataSource 
{ 
public: 
    DataSource(); 
    DataSource(DataSource const& other); 
    virtual ~DataSource(); 

    template <typename WordType> 
    virtual void Put(
     WordType const* const data, 
     unsigned int const wordCount) = 0; 
} 

E questo è dovuto all'impossibilità di gestire una tabella virtuale per fare riferimento a tutti i diversi tipi di tipi possibili con cui questo metodo sarebbe stato istanziato.

Tuttavia, quando si tratta di una funzione membro virtuale di una classe template, sembra essere diverso perché l'intera classe stessa viene "creata" tramite il parametro template quando la variabile di classe template viene instanciata. A questo punto, il metodo virtuale è proprio come qualsiasi altro metodo virual di una classe a causa della natura "find-and-replace" dei template.

In ogni caso, ripetendo la domanda in caso di smarrimento: Le funzioni virtuali virtuali (pure e/o normali) sono consentite all'interno di una classe temporanea?

+5

Suona come hai già capito la risposta a questa ... –

+3

Come ho detto, io giuro a me stesso che ho provato prima e aveva problemi. Quando ha funzionato all'improvviso, volevo essere certo che non fosse solo perché ero su un compilatore diverso, diversi flag di avviso/errore, ecc. E che era stato definito, preferibilmente, che era normale per lo standard. – Anthony

+2

Inoltre, per quello che vale, non ho trovato nulla online che dicesse definitivamente in un modo o nell'altro. Quale posto migliore per mettere queste informazioni di SO? – Anthony

risposta

44

Un modello di classe può effettivamente contenere funzioni virtuali virtuali o pure. Questo è stato impiegato da Andrei Alexandresu in "Modern Design C++" per implementare il modello di visitatore utilizzando modelli e liste di tipi. Puoi vedere il codice here in his Loki library se sei interessato.

Con la maggior parte delle implementazioni C++ standard, questo va bene, perché quando il modello viene istanziato la funzione virtuale finisce per essere una singola funzione. Di conseguenza, il numero di slot necessari nel vtable può essere conosciuto all'interno dell'unità di traduzione, quindi è possibile generare un vtable.

Come accennato, non è possibile avere una funzione membro modello virtuale poiché il numero di slot vtable non sarà noto all'interno dell'unità di traduzione.

Spero che questo aiuti!

6

Le funzioni virtuali virtuali (pure e/o normali) sono consentite all'interno di una classe temporanea?

Sì. Perfettamente legale

6

Pensa a cosa è una classe template - non è una classe in sé, ma un modello che il compilatore può usare per creare classi.

Come tale, non vi è alcun motivo per cui non è possibile includere una funzione virtuale (pura o di altro tipo) nella definizione della classe template, poiché, di per sé, non genera alcun codice, inclusa la tabella virtuale.

Quando realizziamo l'istanza della classe del modello, ad es. DataSource<int>, quindi il compilatore deve solo creare la tabella virtuale per quel tipo selezionato, quindi non è diverso da una funzione virtuale (pura o altrimenti) per una classe non basata su modelli.

1

Un modello di classe con funzioni virtuali è assolutamente soddisfacente. Tuttavia, le funzioni template con parole chiave virtuali con prefisso in classe o classe template non sono consentite.Qui di seguito vi aiutano a ottenere che:

//This is perfectly fine. 
template <type T> 
class myClass{ 
    virtual void function() = 0; 
}; 

//This is NOT OK... 
template<type T> 
class myClass{ 
     template <type T> 
     virtual void function() = 0; 
}; 
Problemi correlati