2

可能重复:
对 vtable 的未定义引用。试图编译一个 Qt 项目

这是代码

#include <iostream>
#include <QApplication>
#include <QTimer>


class myClass : public QObject {
    Q_OBJECT

public:
    QTimer *timer;
    myClass(){
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(mySlot()));
        timer->start(1000);
    }
public slots:
    void mySlot() {
        std::cout << "Fire" << std::endl;
    }
};

int main() {
    std::cout << "Hello, world";
    myClass atimer;
    return 0;
}

除了错误之外,还有两件事我不明白:

  1. 为什么宏后面没有分号,在本例中为 Q_OBJECT。它似乎不遵守 C++ 语法,但人们编写这样的代码。

  2. “public slot”是Qt创建的修饰符,但是gcc编译器怎么还能看懂呢。像 Qt 这样的 IDE 如何修改语言的标准语法?

4

5 回答 5

3

你没有给出确切的错误信息,但我怀疑发生的事情是你没有moc在你的代码上运行,或者你没有编译 moc 生成的代码,或者你没有将代码链接到你的可执行文件/图书馆。

至于你的其他问题:

  1. 宏后不需要分号;预处理器不关心分号——只有编译器关心。因此,您是否需要手动添加分号取决于Q_OBJECT在这种情况下您的宏 ( ) 扩展到什么以及您使用它的位置。在您的情况下,不需要分号。

  2. slots是一个扩展为 emtpy 字符串的宏,因此任何 C++ 编译器都可以处理它。但是,slots也被识别为特殊关键字moc。顺便说signals一下(这是一个扩展为 的宏protected:)。

于 2013-01-11T09:50:30.287 回答
3

这只是因为您qmake自从添加了Q_OBJECT. 只需运行 qmake(如果您使用 QtCreator,它必须在 Build Menu 中)然后编译;)。

希望它有所帮助

于 2013-01-11T10:44:58.433 回答
0

您必须使用 QT 提供的 Meta Object Compiler

于 2013-01-11T10:28:37.737 回答
0

通常,未定义的对 的引用vtable表明您声明了一些虚函数,但从未向它们提供定义。也许Q_OBJECT是在声明什么?

宏在考虑 C++ 语法之前被扩展,以文本形式工作。这就是为什么宏本身不必遵守 C++ 语法的原因。例如,如果Q_OBJECT在其定义的末尾包含一个分号,以便在替换后您得到正确的 C++ 代码,那么这就足够了。

slots也可能是一个宏(甚至可能是一个空的)。然后,在slots用虚无替换后,您将再次获得有效的 C++ 代码。

于 2013-01-11T09:51:00.567 回答
0

一般来说,如果你得到一个未定义的对 vtable 错误的引用,那是因为 qmake 没有运行并moc为它生成了必要的。在项目目录中重新运行 qmake 应该可以修复它,如果没有,则清理构建并再次运行 quake 和 make。

于 2013-01-11T10:38:53.000 回答