5

I am trying to write an Http proxy that basically works like indianwebproxy

So i fired up qtcreator and but one of my classes is failing to compile with the infamous error : undefined reference to vtable for HttpProxyThreadBrowser. I can't figure out why its doing this. I read through similar questions on Stackoverflow and apparently the problem is with undefined virtual methods that are not pure But i have not declared any virtual functions. Here is my class

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

private:
    QTcpSocket outgoingSocket;
    QTcpSocket browserSocket;

};

And I define the class here in pastebin so as not to bore you. Unfortunately i cant find out why the vtable is undefined. Please assist.

httpproxythreadbrowser.cpp:5: undefined reference to `vtable for HttpProxyThreadBrowser
collect2: ld returned 1 exit status
Community
  • 1
  • 1
Dr Deo
  • 4,650
  • 11
  • 43
  • 73
  • According to the [documentation](http://qt-project.org/doc/qt-4.8/qthread.html#run), run is a protected member, not public. I doubt that'd be the source of your error though. – obmarg Mar 09 '12 at 14:06
  • @obmarg: It is, since run is virtual, and he never defined it. – PlasmaHH Mar 09 '12 at 14:26
  • Mmmm... Compiles fine by me. 4.7.4 + 4.8.0 on MinGw. Which OS / Qt ver are you using? – Chris Browet Mar 09 '12 at 14:33
  • @Koying It compiles fines until you try to use the class somewhere, but there is no undefined reference error, so a simple recompilation should fix that error. – alexisdm Mar 09 '12 at 14:48
  • @PlasmaHH Ah, could be it then. The documentation seemed to indicate that it was defined, but I may have misinterpreted. – obmarg Mar 09 '12 at 15:25
  • 1
    For anyone coming here via google: we got this error because of extra spaces in the .pro file – AndrewS Aug 01 '12 at 19:29
  • 2
    @stativ's answer, while not correct in this case, is an incredibly common cause of this error message when using Qt. If you add a new QObject-derived class but forget to add it to the HEADERS variable (or otherwise run moc and link with the resultant objects), this is _precisely_ the error message seen. For lots of people stumbling upon this question, this will be the cause of the problem... – evadeflow Aug 17 '12 at 21:02

4 Answers4

10

The destructor is implicitly virtual because a base class has a virtual d'tor.

The GNU compiler emits the vtable along with the first non-inline virtual method ("key method"). As your d'tor is defined inside the class, it is implicitly virtual, and as there are no other virtual methods, you don't have a key method.

There is no use case where a concrete class would have only virtual inline methods, as they can be inlined only into derived classes.

I'd move the definition of the dtor to the implementation file.

I'm not sure whether you need to use moc here as well, or if QThread derivatives work without (IIRC you need it only for Qt's cast operators, and for signals/slots).

Simon Richter
  • 28,572
  • 1
  • 42
  • 64
7

I had also a undefined reference to vtable error and followed the steps in Undefined reference to vtable... Q_OBJECT macro, that adviced me to run qmake and... it worked!

Community
  • 1
  • 1
Sys
  • 71
  • 1
  • 1
4

You can't copy QTcpSockets, so it may cause other cryptic errors if you try to pass them by copy rather than by address.

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

private:
    QTcpSocket* outgoingSocket;
    QTcpSocket* browserSocket;

And completely recompiling your project may help, when you change header files, because qmake generated Makefile can sometimes fail to notice the changes.

alexisdm
  • 29,448
  • 6
  • 64
  • 99
  • 1
    Another solution is to pass the QTcpSocket's by reference, i.e. HttpProxyThreadBrowser(QTcpSocket & outgoingSocket,QTcpSocket & browserSocket,QObject *parent = 0); – Chris Browet Mar 09 '12 at 15:07
  • Thanks alot guys. But it makes me wonder why i cant copy QTcpSockets but thats a story for another day. – Dr Deo Mar 10 '12 at 06:57
3

This is often caused by not linking the files generated by automoc.

First, you need to run automoc on the headers where classes using Q_OBJECT are defined, in your case "httpproxythreadbrowser.h". This will generate a "*.moc" file.

Now there are two common approaches how to continue. Either you can #include the .moc file at the end of your .cpp file with class definition or you can pass it to the compiler as anoher source file.

stativ
  • 1,452
  • 12
  • 23