【问题标题】:undefined reference to `vtable for myClass' [duplicate]未定义对“myClass的vtable”的引用[重复]
【发布时间】:2013-01-11 09:45:26
【问题描述】:

可能重复:
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. “public slots”是Qt创建的修饰符,但是gcc编译器怎么还能看懂。 Qt 之类的 IDE 如何修改语言的标准语法?

【问题讨论】:

  • 宏只是一个文本替换,所以它可能包含分号,你不必写。
  • 事实上,gcc 编译器不理解public slots(对他来说只是public),但是Qt 的moc 编译器可以。这就是为什么您需要在使用 gcc 编译之前运行它并在之后使用 gcc 编译生成的 moc_....cpp 的原因。最后,这就是为什么一个简单的 gcc 调用对于 Qt 程序来说是不够的(并且可能会导致编译器错误),你应该设置一个正确的 qmake 项目。

标签: c++ qt


【解决方案1】:

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

至于你的其他问题:

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

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

【讨论】:

  • 感谢宏的解释。现在,我所做的就是关注这个视频:youtube.com/watch?v=pHc7siV2Ads 但是,我没有使用单独的标题和源代码进入班级,而是将所有内容合并到一个文件中。无论如何,我已经尝试运行 moc (qmake -project) 并再次重建项目,现在我还有数百个错误。
【解决方案2】:

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

希望对你有帮助

【讨论】:

    【解决方案3】:

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

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

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

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-07-27
          • 2014-06-04
          • 1970-01-01
          • 1970-01-01
          • 2015-09-24
          • 1970-01-01
          • 2011-11-12
          • 1970-01-01
          相关资源
          最近更新 更多