2012-02-10 22 views
6

ho una classe template che eredita da una classe di interfaccia e, pertanto, non ha funzioni virtualiundefined reference to `vtable per un modello

//abstract.h 
class Abstract { 
virtual void abc(); 
Abstract(); 
} 
//Abstract.cpp 
Abstract::Abstract() 
{ //do some init} 

//concrete.h 
class Impl { 
public: 
    void abcImpl(); 
}; 

template<typename T> 
class Concrete : public Abstract, public T { 
virtual void abc(); 
}; 
template<typename T> 
Concrete<t>::abc() { static_cast<T>(*this).abcImpl(); } 

//concrete.cpp 
void Impl::abc() { std::cout << "abc"; } 

Usato qui

//foo.cpp 
Concrete<Impl> *var1 = new Concrete<Impl>(); 

in fase di collegamento, ottengo un errore riferimento indefinito a `vtable for Abstract '

In passato questo errore indicava che il compilatore non riusciva a trovare un posto dove mettere un vtable perché lì s nessun file cpp associato a quella classe. In altre parole, mette il vtable dove prima trova la prima definizione non virtuale di una funzione membro. Ma questo è sconcertante perché. 1. Non sono sicuro perché si lamenta di Abstract - Abstract in realtà ha un cpp 2. Forse msg di errore in realtà significa concreto? Ma Concrete non può essere in un file cpp perché è templatizzato. Quindi, come in generale risolve questo problema quando si ha a che fare con una classe template che ha anche funzioni virtuali?

+4

È questo il codice vero? 'Concrete' non è derivato da' Abstract'. Nota 'Abstract :: abc()' non è una pura funzione 'virtuale' e quindi deve essere definita. – hmjd

+0

possibile duplicato di [simboli non definiti "vtable per ..." e "tipoinfo per ..."?] (Http://stackoverflow.com/questions/1693634/undefined-symbols-vtable-for-and-typeinfo-for) –

risposta

3

Il problema potrebbe essere dovuto al metodo abc() non dichiarato come virtuale puro. Ad esempio, GCC utilizzerà abc() come metodo chiave per il posizionamento vtable, poiché è il primo metodo virtuale non in linea non puro dichiarato nella classe (dettagli: http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html). Se dichiari abs() puro virtuale, dovrebbe posizionare vtable in Abstract.cpp dove è definito il costruttore.

Problemi correlati