2012-02-10 17 views
6

tengo una clase de plantilla que hereda de una clase de interfaz y por lo tanto tiene funciones virtualesreferencia indefinida a `vtable para una plantilla

//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"; } 

Se utiliza aquí

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

En el momento del enlace, Puedo obtener una error referencia indefinida a `vtable para resumen '

En el pasado, este error indicaba que el compilador no podía encontrar un lugar para poner un vtable porque wa s no hay archivo cpp asociado con esa clase. En otras palabras, pone el vtable donde primero encuentra la primera definición no virtual de cualquier función miembro. Pero esto es desconcertante porque. 1. Im no está seguro de por qué se queja de Resumen - Resumen en realidad tiene un cpp 2. Tal vez el mensaje de error en realidad significa concreto? Pero Concrete no puede estar en un archivo cpp porque está templado. Entonces, ¿cómo se resuelve en general este problema cuando se trata de una clase de plantilla que también tiene funciones virtuales?

+4

¿Es este el código real? 'Concrete' no se deriva de' Abstracto'. Nota 'Abstract :: abc()' no es una función pura 'virtual' y, por lo tanto, debe estar definida. – hmjd

+0

posible duplicado de [Símbolos no definidos "vtable for ..." and "typeinfo for ..."?] (Http://stackoverflow.com/questions/1693634/undefined-symbols-vtable-for-and-typeinfo-for) –

Respuesta

3

El problema puede deberse al método abc() no declarado como puramente virtual. Por ejemplo, GCC usará abc() como el método clave para la ubicación de vtable, porque es el primer método virtual no puro en línea declarado en la clase (detalles: http://gcc.gnu.org/onlinedocs/gcc/Vague-Linkage.html). Si declara abs() virtual puro, debe colocar vtable en Abstract.cpp donde se define el constructor.

Cuestiones relacionadas