Qt Linker Error: "undefined reference to vtable" [duplicate]

Any time you add a new call to the Q_OBJECT macro, you need to run qmake again. The vtables issue you're referring to is directly related to that.

Just run qmake and you should be good to go assuming there are no other issues in your code.


I've seen a lot of ways to solve the problem, but no explanation for why it happens, so here goes.

When the compiler sees a class with virtual functions (directly declared or inherited), it must generate a vtable for that class. Since classes are generally defined in headers (and thus appear in multiple translation units), the question is where to place the vtable.

In general, the problem can be solved by generating the vtable in every TU* where the class is defined, and then let the linker eliminate duplicates. Since class definitions are required to be the same on every occurrence by the ODR**, this is safe. However, it also slows down compilation, bloats object files, and requires the linker to do more work.

As an optimization, therefore, compilers will, when possible, choose a specific TU to put the vtable in. In the common C++ ABI***, this TU is the one where the key function of the class is implemented in, where the key function is the first virtual member function that is declared in the class, but not defined.

In the case of Qt classes, they usually start with the Q_OBJECT macro, and this macro contains the declaration

virtual const QMetaObject *metaObject() const;

which, since it is the first virtual function in the macro, will generally be the first virtual function of the class and thus its key function. The compiler will therefore not emit the vtable in most TUs, only the one that implements metaObject. And this function's implementation is written automatically by moc when it processes the header. Thus, you need to have moc process your header to generate a new .cpp file, and then include the .cpp file in your compilation.

So when you have a new header that defines a QObject-derived class, you need to rerun qmake so that it updates your makefiles to run moc on the new header and compile the resulting .cpp file.

* TU: Translation Unit. A term of art in C and C++, it refers to a single source file plus all the header files transitively included from it. Basically, the stuff the compiler sees when it works on a single source file.

** ODR: One Definition Rule. A set of rules in the C++ standard that define what happens when things (functions, classes, etc.) are defined multiple times in different translation units.

*** ABI: Application Binary Interface. A description of the way the code is organized when compiled, necessary for object files to be linked together. The Common C++ ABI is a specification that compilers for Linux generally follow so that they can interoperate.


I ran into this error after I created a little class inside a small "main.cpp" file that I had created to test something.

After futzing for an hour or so, I finally moved that class out of main.cpp and into a standalone hpp file, updated the .pro (project) file and the project then built perfectly fine. That may not have been the issue here but I figured it would be useful information anyway.