Qt Undefined Reference To - c++

I had some messy code so I finally seperated it into headers and sources, but now I get 136 warnings saying
inline function 'void suchandsuch()' used but never defined
and errors
undefined reference to 'Widget::Widget(QWidget*)'
I've tried QMake, all the sources are in .pro file, rebuilding, cleaning and deleting all the moc files.

The first problem is in the inline functions. If you're familiar with template functions, inline functions have the same requirements. They need to have their implementation details included in the header file so that the compiler can generate the code inline whenever its included somewhere else. You can't implement then in the regular .cpp file.
As for the second problem, if Widget::Widget() is referring to the QWidget class and wasn't copy pasted from the error log, I'm guessing that it means your code isn't linking properly against the QtGui library. Make sure the .pro file doesn't have a line removing it as its otherwise included by default (aka, you don't want a line saying QT -= gui).
If that's not the problem and the Widget class it can't find a Widget(QWidget*) constructor for is your own class, then the problem might just be that there isn't an implementation in the widget's .cpp file for a Widget::Widget(QWidget*) function.

Related

When do I have to include moc*.cpp in Qt?

I understand the basic concept of why it is better to manually include moc*.cpp instead of leaving moc to do it itself, but I don't quite understand when I have to include it.
Let's say I have mainwindow.cpp and mainwindow.hpp, that require the moc to run on them. Here, I know I have to include moc_mainwindow.cpp in mainwindow.cpp (and not in mainwindow.hpp).
But what if I have foo.cpp that includes mainwindow.hpp, do I have to include moc_mainwindow.hpp in foo.cpp? It just isn't clear to me how this whole moc thing works, so can someone explain this? (and, yes, I did research this on the internet - I read the Qt Documentation about moc but it didn't make it clear to me).
The moc’ed file contains the implementation of the meta object, the signal-slot sugar and few other things. It means that if you compile it more than once you will have duplicated symbols on linking stage.
Actually your best option would be to not include the moc’ed file and add it as other normal compilation unit of your project. It simplifies your code, prevents linkage errors, and have a good impact in your compilation time when implementation files are modified.
Nevertheless, if you decide to include the moc’ed file manually you have to do it only in one place to prevent the aforementioned duplicated implementations.
Another case where a direct include is useful for expressiveness is when you declare a class with the Q_OBJECT in a .cpp file: including the moc’ed in the same file is coherent with the fact that such class belongs to only that file.

Why is important to include ".moc" file at end of a Qt Source code file?

Why is it important to add an include for .moc file in a Qt cpp source code?
This is a common step used in several Qt samples, including this one:
http://doc.qt.io/qt-5/qttestlib-tutorial1-example.html; where the line #include "testqstring.moc" should be included in the end of the file.
I don't understand exactly why this is necessary.
It's necessary if you define QObject subclasses with the Q_OBJECT macro in a .cpp file. When you do so:
qmake must generate rules inside your Makefile to invoke moc on that .cpp file.
That special (hackish?) inclusion triggers qmake to do so, and tells it which would be moc's output file (teststring.moc) when invoked on your .cpp.
In order to compile moc's output (which is still a bunch of C++ code) the compiler must see your class definition. Otherwise, it will complain that there's no such thing as YourClass::staticMetaObject and similar, because it has no idea that YourClass exists.
Typically one defines classes featuring Q_OBJECT in a header file. moc then adds a #include "header.h" into its generated output, and this means moc's output can be happily compiled.
But what if your class definition is inside a .cpp? You can't #include a .cpp file in moc's output, as that would give you tons of redefinition errors.
Instead, you #include moc's output in your .cpp, so that it gets compiled together and everyone is happy. (This means qmake will only emit one rule saying to run moc, but not another rule telling the compiler to compile moc's output.)
From 2. you can also also desume that defining classes with Q_OBJECT in a .h does not require any special inclusion.
Make an addition:
When Q_OBJECT in xxx.h, after qmake, the system will generate a moc_xxx.cpp with xxx.h in it.
When Q_OBJECT in xxx.cpp, after qmake, the system will generate a xxx.moc, and you need to add the .moc file into the .cpp file.

Multiple definiton of function when including library

I try to include headers from a library in different files of my project and I get multiple definition errors on some functions of the library.
After reading the answer to this question I think the problem is that the functions are implemented directly in the header files of the library.
In particular I want to include the files codecfactory.h and deltautil.h from FastPFor. I don't know if it is relevant for my problem but I include it into my cmake project with this code in my CMakeLists.txt:
include_directories(../../FastPFor/headers)
add_library(FastPFor STATIC ../../FastPFor/src/bitpacking.cpp
../../FastPFor/src/bitpacking.cpp
../../FastPFor/src/bitpackingaligned.cpp
../../FastPFor/src/bitpackingunaligned.cpp
../../FastPFor/src/horizontalbitpacking.cpp
../../FastPFor/src/simdunalignedbitpacking.cpp
../../FastPFor/src/simdbitpacking.cpp
${HEADERS}
)
Everything works fine if I just include the files once. But as soon as I use them in two .cpp files I get these kinds of errors:
CMakeFiles/dbgen.bin.dir/queries/Query5.cpp.o: In function `vsencoding::BitsWriter::BitsWriter(unsigned int*)':
Query5.cpp:(.text+0x8420): multiple definition of `vsencoding::BitsWriter::BitsWriter(unsigned int*)'
CMakeFiles/dbgen.bin.dir/queries/Query13Naive.cpp.o:Query13Naive.cpp:(.text+0x7a50): first defined here
Is there any way I can fix this without having to change the FastPFor code but only my own?
The question you linked to says it all - there is no way to solve this without modifying the headers (or just include them in only one source file).
For instance this line defines a non-inline constructor in a header. Including it in more than one translation unit would result in a violation of the ODR rule.
One way to workaround this would be to change your project to header only style, i.e. moving your implementation to header files. In this way you can keep (more ore less) the structure of your project.
However, this is definitely not a nice solution... The whole project needs to be compiled after every small change to one of the headers...

Qt: LNK2001 and LNK2019 Errors arise after implementing a signal/slot across source files

This consists of the declarations in my MainWindow file, I haven't included the library inclusions for brevity. I have included QObject.h in both, and all required libraries. It was compiling fine before the inclusion of the second connect call. The first Ctrl-C handler works fine.
I took out my code, thought my employer wouldn't like it. See the appropriate response below!
I am using QT Creator. When I googled these error messages, most of the solutions provided revolved around fixing the make command/path or something of the sort which occurs when compiled in Visual Studio.
I reiterate, these errors showed up ONLY after the inclusion of that second connect call of the global GCamera and the MainWindow. The program was compiling and running before this.
Thank you in advance, I apologize for the lengthy post and look forward to receiving any input.
You should have a file named moc_tcamera.cpp that implements the missing symbol in the build directory.
If it isn't present, you should "run qmake", and "Rebuild" your project (both actions are in Qt Creator Build menu).
Why the error occured:
qmake adds a moc (Qt's meta object compiler) step to the Makefile for all the source files that contains the macros Q_OBJECT or Q_GADGET, such file is said to be "mocable". Once a file is detected as mocable or non mocable, that status doesn't change until qmake is rerun.
QtCreator only runs qmake by itself when the .pro file changes (for example, when you add or remove a file).
It means you probably compiled the project once without the Q_OBJECT macro in the file tcamera.h, and added that macro afterward. And because you didn't need the meta object until you added the call to connect, VC++ didn't try to resolve the missing symbols.
You can get linker errors when you, say, include the header in your .pro file, but not the source. For example in your .pro file:
HEADERS += t_camera.h foo.h
SOURCES += foo.cpp
would cause you to have linker errors, typically LNK2001 and LNK2019. However, IIRC QtCreator manages the .pro files for you, right? In other words, make sure your .pro file is correct. I'd be surprised if it wasn't, but errors in the .pro file can cause the issue you're seeing.

Qt vtable error

I'm going through the old Trolltech Qt tutorials as I find them more helpful than the newer ones and an undefined reference to vtable error hits me when I got to a class widget implementing its own signals.
http://doc.trolltech.com/4.0/tutorial-t7.html
Instead of keeping the code separate, I just copied them all in the same .cpp for convenience.
I snooped around and found that a vtable error is caused by an undefined virtual function. However, I didn't omit anything from the tutorial code except the code separation. Omitting the Q_OBJECT macro from lcdrange.h as well as the slots and signals seem to make the project compile. I figure it's void valueChanged(int newValue); at lcdrange.h that is causing the fuss but the tutorial did not provide a definition. I'm sure they won't post code that isn't working so I must be doing something wrong. I'm using C::B(MinGW) if that means anything. I'm also new to C++.
MOC must generate code for lcdrange.h and the generated code must be compiled and linked.
qmake ensures this for all header files listed in the HEADERS variable.
Make sure lcdrange.h is listed in the HEADERS section of your .pro file, and rerun qmake.