2012-03-09 26 views
5

estoy tratando de escribir un proxy HTTP que básicamente funciona como indianwebproxyreferencia indefinida a VTABLE para ...

Así que dispararon hasta QtCreator y pero una de mis clases está fallando a compilar con el error infame: undefined reference to vtable for HttpProxyThreadBrowser. No puedo entender por qué está haciendo esto. Leí preguntas similares sobre Stackoverflow y aparentemente the problem is with undefined virtual methods that are not pure Pero no he declarado ninguna función virtual. Aquí está mi clase

class HttpProxyThreadBrowser : public QThread 
{ 
public: 
    HttpProxyThreadBrowser(QTcpSocket outgoingSocket,QTcpSocket browserSocket,QObject *parent = 0); 
    ~HttpProxyThreadBrowser(){}; 
    void run(); 

private: 
    QTcpSocket outgoingSocket; 
    QTcpSocket browserSocket; 

}; 

Y defino la clase aquí en pastebin para que no se le dio a luz. Desafortunadamente no puedo descubrir por qué el vtable no está definido. Por favor asiste.

httpproxythreadbrowser.cpp:5: undefined reference to `vtable for HttpProxyThreadBrowser 
collect2: ld returned 1 exit status 
+0

De acuerdo con la [documentación] (http://qt-project.org/doc/qt-4.8/qthread.html#run), ejecutar es un miembro protegido, no público. Sin embargo, dudo que esa sea la fuente de tu error. – obmarg

+0

@obmarg: Lo es, ya que ejecutar es virtual, y nunca lo definió. – PlasmaHH

+0

Mmmm ... Compila bien por mí. 4.7.4 + 4.8.0 en MinGw. ¿Qué OS/Qt ver estás usando? – Koying

Respuesta

4

No puede copiar QTcpSocket s, por lo que puede causar otros errores crípticos si intenta pasarlos por copia en lugar de por dirección.

HttpProxyThreadBrowser(QTcpSocket * outgoingSocket,QTcpSocket * browserSocket,QObject *parent = 0); 

private: 
    QTcpSocket* outgoingSocket; 
    QTcpSocket* browserSocket; 

Y completamente recompilar su proyecto puede ayudar, al cambiar los archivos de cabecera, ya que genera qmake Makefile a veces puede dejar de notar los cambios.

+1

Otra solución es pasar el QTcpSocket por referencia, es decir, HttpProxyThreadBrowser (QTcpSocket & outgoingSocket, QTcpSocket & browserSocket, QObject * parent = 0); – Koying

+0

Muchas gracias chicos. Pero me hace preguntarme por qué no puedo copiar QTcpSockets, pero esa es una historia para otro día. –

3

Esto a menudo se produce al no vincular los archivos generados por automoc.

En primer lugar, debe ejecutar automoc en los encabezados donde se definen las clases que utilizan Q_OBJECT, en su caso "httpproxythreadbrowser.h". Esto generará un archivo "* .moc".

Ahora hay dos formas comunes de cómo continuar. O puede #incluir el archivo .moc al final de su archivo .cpp con la definición de clase o puede pasarlo al compilador como un archivo fuente adicional.

10

El destructor es implícitamente virtual porque una clase base tiene un servidor virtual.

El compilador GNU emite el vtable junto con el primer método virtual no en línea ("método clave"). Como su nombre está definido dentro de la clase, es implícitamente virtual, y como no hay otros métodos virtuales, no tiene un método clave.

No hay ningún caso de uso en el que una clase concreta tenga solo métodos en línea virtuales, ya que solo se pueden insertar en clases derivadas.

Movería la definición del dtor al archivo de implementación.

No estoy seguro de si necesita usar moc aquí también, o si los derivados QThread funcionan sin (IIRC lo necesita solo para operadores de transmisión de Qt, y para señales/ranuras).