3

可能重复:
Qt:信号和插槽错误:未定义的对 `vtable 的引用

这里我们有 test.cpp:

#include <QApplication>
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

单独放置在新目录中并:

$ qmake -project
$ qmake
$ make

它不起作用:

test.o: In function `MainWindow::~MainWindow()':
test.cpp:(.text._ZN10MainWindowD2Ev[_ZN10MainWindowD5Ev]+0x3): undefined reference to `vtable for MainWindow'
test.cpp:(.text._ZN10MainWindowD2Ev[_ZN10MainWindowD5Ev]+0xb): undefined reference to `vtable for MainWindow'
test.o: In function `main':
test.cpp:(.text.startup+0x48): undefined reference to `vtable for MainWindow'
test.cpp:(.text.startup+0x51): undefined reference to `vtable for MainWindow'
test.o: In function `MainWindow::~MainWindow()':
test.cpp:(.text._ZN10MainWindowD0Ev[_ZN10MainWindowD0Ev]+0x7): undefined reference to `vtable for MainWindow'
test.o:test.cpp:(.text._ZN10MainWindowD0Ev[_ZN10MainWindowD0Ev]+0xf): more undefined references to `vtable for MainWindow' follow
collect2: error: ld returned 1 exit status
make: *** [tmp] Error 1

一般来说,这样的错误要么是因为 moc 没有被调用,要么是因为未实现的虚拟方法。

moc 应该由 qmake 自动调用,而 afaik QMainWindow 没有任何纯虚拟方法 - 那么这里的问题是什么?

当我删除 Q_OBJECT 时,它可以工作。为什么是这样?到底是怎么回事?

我看到 Q_OBJECT 告诉 moc 为该对象生成信号/插槽元数据,为什么在这种情况下不能这样做?

更新:

解决方案是在类下面添加#include "test.moc"

#include <QApplication>
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT
};

#include "test.moc"  // <----------- HERE

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}
4

1 回答 1

10

这是因为您在 .cpp 文件中声明了该类。将其放入单独的 .h 标头中。

默认情况下,不会为源文件调用 MOC,仅针对标头调用(编辑:根据@Kamil,MOC 是针对 .cpp 源文件运行的,除了生成的 .moc 文件应该#include在 .cpp 文件中手动 -d - - 请参阅下面的编辑)。

然后,将相应的头文件添加到 .pro 文件内的 HEADERS 变量中。

当然,#include同样的头文件放入test.cpp。

另外,请在此处查看此答案:

https://stackoverflow.com/a/5854884/1284631

编辑:

根据这个线程:http ://www.qtcentre.org/threads/28580-Why-does-qmake-moc-only-process-header-files

要强制为 .cpp 文件运行 MOC,您应该添加:

#include "test.moc"

就在你的班级定义的正下方。并重新运行 qmake。但是,我没有对此进行测试。

编辑2:有关OP正在寻找的内容的讨论,请参见此参考:

http://harmattan-dev.nokia.com/docs/library/html/qt4/moc.html

于 2013-01-11T14:36:54.773 回答