1

This might be the next duplicate, but nevertheless I do not find the error in this code:

#include <qwt_plot.h>

class QLinePlot : public QwtPlot
{
    Q_OBJECT
public:
    QLinePlot(QWidget* parent = 0, Qt::WindowFlags flags = 0): QwtPlot(parent)
    {
    }

    ~QLinePlot()
    {
    }

};


int main( int argc, char **argv )
{
    QLinePlot * plot = new QLinePlot();
}

I deleted the build folder and also ran qmake again, but no change. The error message is

test.cpp:7: undefined reference to `vtable for QLinePlot'
Matthias Pospiech
  • 3,130
  • 18
  • 55
  • 76
  • 1
    The top related link is http://stackoverflow.com/questions/1552069/undefined-reference-to-vtable-trying-to-compile-a-qt-project?rq=1, and this sure looks like an exact duplicate of that. If it's not, and if you understand the answers given there, can you edit your question to explain why your question is different? –  Oct 25 '16 at 20:10
  • do you have the class definition in a cpp ? if yes, move it to a header .. – HazemGomaa Oct 25 '16 at 20:17
  • @H.G In that case you raise a very good point, I stand corrected. –  Oct 25 '16 at 20:28
  • Perhaps it is failing to link a required library – M.M Oct 25 '16 at 21:23
  • This is a duplicate of http://stackoverflow.com/q/3001615/1329652 – Kuba hasn't forgotten Monica Oct 25 '16 at 21:25
  • 1
    @H.G. `moc` processes any valid C++ source code. Headers are not special in any way: usually all `.h` and `.cpp` files are supposed to be valid C++, unless you messed up or are doing some macro metaprogramming tricks. Thus you can pass either `.h` or `.cpp` through moc. And to indicate that there's moc-able content in `foo.cpp` you need to append `#include "foo.moc"` at the end of the file. That's all. Then re-run `qmake` and you're set! – Kuba hasn't forgotten Monica Oct 25 '16 at 21:29
  • @KubaOber right ! but that's the point ... moc process headers pain free .. you can avoid adding "foo.moc" if you define your Q_OBJECT call in header ! – HazemGomaa Oct 25 '16 at 21:57
  • @H.G. Actually - moc doesn't care one iota. qmake does care, since qmake generates the makefiles that eventually invoke moc. It's qmake that could - if anyone cared to implement it - make moc-wrapping of cpp files automatic. Alas, it doesn't do so. The `#include "foo.moc"` is an idiom in Qt: you need to know what it means and when to use it. – Kuba hasn't forgotten Monica Oct 26 '16 at 12:44

2 Answers2

3

You're missing an #include "test.moc" at the end of your file:

// test.cpp
#include <qwt_plot.h>

class QLinePlot : public QwtPlot
{
    Q_OBJECT
public:
    using QwtPlot::QwtPlot;
};


int main( int argc, char **argv )
{
    QLinePlot plot;
}

#include "test.moc"

After adding the include line, you must re-run qmake on the project.

Your example is hardly minimal, though. All you need to reproduce the issue would be:

#include <QObject>
class Foo : public QObject {
  Q_OBJECT
  ~Foo() {}
}
int main() { Foo foo; }
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • I prefer the solution with header and cpp file, but since I was using only a cpp file this is the correct solution. – Matthias Pospiech Oct 31 '16 at 09:24
  • If the `QObject`-deriving class is used locally in one source file, it probably makes little sense to push it out to its own header - and then you'll want to include the moc output at the end of the `.cpp` file :) – Kuba hasn't forgotten Monica Oct 31 '16 at 12:37
0

you should have your QLinePlot class in a header file test.h. This is cleaner, and you don't need to include test.moc in your test.cpp. for example

test.cpp

#include "test.h"
int main( int argc, char **argv )
{
  QLinePlot plot;
}

test.h

#include <qwt_plot.h>
class QLinePlot : public QwtPlot
{
   Q_OBJECT

   // stuff
};
HazemGomaa
  • 1,620
  • 2
  • 14
  • 21