Qt中关于undefined reference to `vtable for故障总结

时间:2022-10-01 05:34:28

在Qt中,undefined reference to ‘vtable for 通常出现在打开了宏 Q_OBJECT的程式当中。我遇到的情况是:

将类体及类体实现直接写到main.cpp里,没有包含 moc文件。这是一种常见的C++错误,通常就是类体中声明的虚函数没有找到实体。有时候你会说,我没有声明虚函数啊,怎么出来的? 那么建议你 Ctrl+左键追踪一下Q_OBJECT这个宏,这个宏其实默认给你的类加入了一些虚函数的声明(关于signal-slot实现的关键设施),而其实现实在moc_xx.cpp中自动生成的,如果你的编译过程没有产生这个文件,或者产生的这个文件没有参与到编译链接中去,那么就会发生这个错误。

现将一篇文章收录于此,以备查阅:

undefined reference to ‘vtable for 常见情况:

一:预编译器打开宏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文件的错误。  

二:undefined reference to vtable for "xxx::xxx"  今天碰到了这个问题。  原因: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,从而形成信号接力.