未定义引用`vtable for myClass'

时间:2013-01-11 09:45:27

标签: c++ qt

  

可能重复:
  Undefined reference to vtable. Trying to compile a Qt project

这是代码

#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. “公共插槽”是由Qt创建的修饰符,但是为什么gcc编译器仍然可以理解它。像Qt这样的IDE如何修改语言的标准语法?

5 个答案:

答案 0 :(得分:3)

您没有提供确切的错误消息,但我怀疑发生的事情是您没有在代码上运行moc,或者您没有编译由moc生成的代码,或者您没有将代码链接到您的可执行文件/库中。

至于你的其他问题:

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

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

答案 1 :(得分:3)

这只是因为你没有qmake,因为你已经Q_OBJECT了。只需运行qmake(如果你使用QtCreator,它必须在Build菜单中)然后编译;)。

希望有所帮助

答案 2 :(得分:0)

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

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

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

答案 3 :(得分:0)

您必须使用QT提供的元对象编译器

答案 4 :(得分:0)

一般情况下,如果您获得了对vtable错误的未定义引用,那是因为qmake尚未运行并为其生成必要的moc。在项目目录中重新运行qmake应该修复它,如果没有,那么清理构建并运行quake并重新制作。