Qt 出现“Qt 出现“undefined reference to `vtable for”原因总结

本文详细解析了在Qt编程过程中遇到的undefined reference to `vtable for`链接错误,并提供了多种解决方法,包括如何正确处理Q_OBJECT宏及moc工具的使用。

qt写了个程序,编译没问题,连接的时候出现了这样的错误:undefined reference to `vtable for.......

郁闷了很久,后来百度了一下,找到了解决方法,摘录如下以记忆。

由于Qt本身实现的机制所限,我们在使用Qt制作某些软件程式的时候,会碰到各种各样这样那样的问题,而且很多是很难,或根本很难找到原因的,即使解决了问题,假如有人问您为什么,您只能回答--不知道;
今天我在这里列举的问题也是再编写Qt程式时,总是碰到的问题,问题普遍,而答案却不唯一,解释这一个问题的说法很多,往往只适合某一种情况,因为这个错误太笼统了,他就是-- “undefined reference to `vtable for”可能您看着很熟悉,似乎在c++程式中也碰到过这个问题,您说对了,有时候这个错误,不只是qt的原因,更有您的c++程式的原因;
下面搜集了网上的一些出现的现象,对应解决方法,原因,基本上我都验证过,收录于此,以做备份;
一:
预编译器打开宏Q_OBJECT,声明若干个由moc处理(implement)的成员函数。假如得到类似于“undefined reference to vtable for LcdNumber”的编译错误(if you get compiler errors along the lines of "undefined reference to vtable for LcdNumber"),您可能是忘记了执行moc,或忘记了将moc输出加入到link命令里。
某一个类中假如加入Q_OBJECT后,则link时提示:undefined reference to vtable for "xxx::xxx".删掉他则没有任何问题.
解决:尝试(1):把任何的obj文档和uic文档删除,重新编译.仍然失败.
去trolltech的mail lists找到原因: 因为qmake生成Makefile的时候,这个类的头文档中并没有Q_OBJECT,所以在相应的Makefile里面并没有用moc xxx.h命令,最终导致链接失败.重新运行qmake,问题解决.
在查找解决方法的时候,附带发现一点:
qmake 不会处理.cpp文档里的Q_OBJECT,所以,假如在.cpp文档中有他的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文档,再包含到.cpp里面去,才能解决这个问题.
这里能够发现问题的出现是因为没有moc生成相应的moc文档,之后连接就出问题。
我找了好多源码之类的问题,就是没有找pro的错误,后来想到qt中moc我们是有make做的
qt的make编译是根据Makefile来的,而Makefile是由pro文档来的。这才想到了找pro文档的错误。
from: http://www.cublog.cn/u/16292/showart_136087.html

二:
undefined reference to vtable for "xxx::xxx"
今天碰到了这个问题,终于被我google到了:
http://www.cublog.cn/opera/showart.php?blogid=8650&id=49526
原 因:qmake不会处理.cpp文档里的Q_OBJECT,所以,假如在.cpp文档中有他的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文档,再包含到.cpp里面去,才能解决这个问题.
其他:
1.问题: QGLViewer中的函数不能正常link.解决: 翻看其源代码,发现是因为从源码安装libQGLViewer时,编译用了Qt 3,而我的程式中用Qt4 编译.所以必须重新用Qt4编译.但是,更改QTDIR 环境变量为Qt4后,重新编译的话,qmake生成makefile时就提示出错.进一步发现,是因为虽然设了QTDIR为Qt4,头文档和库文档都会使 用Qt4,但是moc,uic等都是用的qt3版的,再把PATH环境变量改变后,一切ok.
2.问题:某一个类中假如加入Q_OBJECT后, 则link时提示:undefined reference to vtable for "xxx::xxx".删掉他则没有任何问题.解决:尝试(1):把任何的obj文档和uic文档删除,重新编译.仍然失败.去trolltech的 mail lists找到原因: 因为qmake生成Makefile的时候,这个类的头文档中并没有Q_OBJECT,所以在相应的Makefile里面并没有用moc xxx.h命令,最终导致链接失败.重新运行qmake,问题解决.在查找解决方法的时候,附带发现一点:qmake 不会处理.cpp文档里的Q_OBJECT,所以,假如在.cpp文档中有他的话,也会产生undefined reference to vtable for "xxx::xxx". 这时,需要先用moc xxxx.cpp生成相应的moc文档,再包含到.cpp里面去,才能解决这个问题.
3. 看Qt的reference发现: 能够connect(pObjA, SIGNAL(someSignalA()),pObjB,SIGNAL(someSignalB()));这样pObjA发出的someSingalA 会导致pObjB发出someSignalB,从而形成信号接力.
 

### 常见原因分析 在 Qt 6.9.1 项目中使用 `qmake` 编译时,出现 `undefined reference to vtable for MainWindow` 和 `MainWindow::staticMetaObject` 错误,通常是由于以下原因导致的: - 项目中使用了 `Q_OBJECT` 宏,但未正确执行 `qmake`,导致元对象编译器(moc)未生成所需的元对象代码。这种情况下,链接器无法找到虚函数表(vtable)和元对象信息,从而报错[^2]。 - 类 `MainWindow` 继承自 `QMainWindow` 或 `QWidget` 等基类,但未正确实现其虚函数,或者构造函数、析构函数未正确定义。 - `.pro` 文件中未包含 `QT += widgets` 或其他必要的模块,导致编译器无法识别 Qt 核心功能。 - 源文件未正确添加到 `.pro` 文件中,`qmake` 未将其纳入构建流程。 ### 解决方法 为解决上述问题,需确保以下步骤正确执行: 1. **确保正确使用 `Q_OBJECT` 宏并执行 `qmake`** 如果 `MainWindow` 类中使用了 `Q_OBJECT` 宏,则必须在修改后重新运行 `qmake`,以便 moc 工具生成相应的元对象代码。仅执行构建操作不会触发 moc 的重新编译,因此必须手动执行 `qmake`[^2]。 ```qmake # MainWindow 类定义 class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = nullptr); ~MainWindow(); }; ``` 2. **确保 `.pro` 文件中包含必要的 Qt 模块** 如果使用了 `QMainWindow` 或 `QWidget`,则 `.pro` 文件中应包含 `QT += widgets`,否则应根据使用情况添加 `gui` 或 `core` 模块。 ```qmake QT += core gui widgets TARGET = MyApp TEMPLATE = app SOURCES += main.cpp \ mainwindow.cpp HEADERS += mainwindow.h ``` 3. **确保所有源文件已添加到 `.pro` 文件中** 如果 `mainwindow.cpp` 或 `mainwindow.h` 未添加到 `.pro` 文件的 `SOURCES` 或 `HEADERS` 中,则 `qmake` 无法识别这些文件,导致链接失败[^4]。 4. **确保类的虚函数已正确定义** 如果 `MainWindow` 继承自某个包含纯虚函数的类,必须确保所有虚函数都已实现。否则,链接器会因找不到虚函数表而报错[^2]。 5. **确保 moc 文件正确生成** 如果 `qmake` 执行后未生成 `.moc` 文件(如 `moc_mainwindow.cpp`),则可能需要手动运行 `moc` 工具或清理项目后重新执行 `qmake` 和构建操作。 ```bash qmake make clean make ``` 6. **确保析构函数为 `virtual`** 如果 `MainWindow` 是某个类的子类,并且其父类有虚函数,则析构函数应声明为 `virtual`,以确保多态析构时虚函数表正确绑定。 ```cpp // MainWindow 析构函数应为 virtual virtual ~MainWindow(); ``` ### 其他注意事项 - 如果 `MainWindow` 的定义和实现被写在 `main.cpp` 中,可能会导致 moc 无法正确识别其 `Q_OBJECT` 宏,从而不生成元对象代码。建议将类定义和实现分离到 `.h` 和 `.cpp` 文件中。 - 若项目中使用了 UI 文件(`.ui`),确保 `.pro` 文件中包含 `QT += widgets`,并且未手动删除 `.moc` 文件。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值