Qt经典错误:undefined reference to `vtable for XXX'
Qt经典错误:undefined reference to `vtable for XXX'
问题描述
有两种出现场景:
- 当 .cpp 文件中使用了 Qt 的元对象系统,即使用了
O_OBJECT
、Q_PROPERTY
、signal/slot
等这种需要由 moc 工具处理编译的宏时 - 当程序中出现虚函数没有实现时
解决方案
场景1:
场景1出现的原因在于最终的 Makefile 里没有将 moc_xxx.cpp 加入编译引起,而这个依赖关系是由 moc 工具写入到 makefile 中的。
Qt 的 moc 工具只会扫描 .h 头文件,因此其他后缀的文件中的 O_OBJECT
、Q_PROPERTY
将不会被处理。
这种情况的解决方案就是将所有的 O_OBJECT
、Q_PROPERTY
、signal/slot
等挪到 .h 文件,或者手动生成 moc 文件然后在用到这些元对象系统的文件末尾加上 #include "文件名.moc"
手动生成.moc文件方法
在Qt安装目录下,找到moc.exe工具,手动生成.moc文件。
现在程序变成这样:
// 原cpp文件,末尾添加include .moc 文件 class SendMsg : public QObject { Q_OBJECT }; #include "main.moc" int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); SendMsg m_sendMsg; return a.exec(); }
QObject 宏编译展开得到的虚函数声明:
moc文件中将这些虚函数实现了,因此没有找到 moc 文件就会报错:
出现这种情况的原因还可能是在执行qmake的时候.h代码里并没有O_OBJECT这样的代码。而执行make的时候.h里已经有Q_OBJECT了,解决的方法就是重新执行qmake,然后执行make。
场景2:
场景2出现的原因也有两种表象,这也提醒我们 override
关键字的好处。
如果是派生类没有实现基类的虚函数,检查并实现即可。这种情况很容易忘记实现虚析构函数,这就体现在函数声明末尾加 = default
或 {}
的好处。
如果是派生类都实现了基类的虚函数,但基类是一个抽象类(即含有纯虚函数),则就必须防止基类在某处做了模板参数。
本文作者:3的4次方
本文链接:https://www.cnblogs.com/3to4/p/18022402
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步