Qt經典出錯信息之undefined reference to `vtable for classname


這個出錯信息太常見了,用過Qt兩個月以上的朋友基本上都能自己解決了,因為太經典了,可以給新手參考。

出錯信息一般類似:undefined reference to `vtable for classname MyWidget`
在執行make命令后出現。

出錯原因是在定義類的時候為了能使用signals和slot,在類定義的后面加了Q_OBJECT引起。 因為Q_OBJECT是一個宏,在不同的類中展開是不同的代碼,例如在mywidgeth.h中生成的

public: template inline void qt_check_for_QOBJECT_macro(const T &_q_argument) const { int i = qYouForgotTheQ_OBJECT_Macro(this, &_q_argument); i = i; } static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); static inline QString tr(const char *s, const char *c = 0) { return staticMetaObject.tr(s, c); } static inline QString trUtf8(const char *s, const char *c = 0) { return staticMetaObject.trUtf8(s, c); } static inline QString tr(const char *s, const char *c, int n) { return staticMetaObject.tr(s, c, n); } static inline QString trUtf8(const char *s, const char *c, int n) { return staticMetaObject.trUtf8(s, c, n); } virtual int qt_metacall(QMetaObject::Call, int, void **); private:

可以看到以上的代碼聲明了3個從父類繼承的3個虛函數。本來這三個函數的實現應該是由moc_mywidget.cpp來完成。
而當前的錯誤正是因為Makefile里沒有將moc_mywidget.cpp加入編譯引起。

Makefile背后的原因是qmake,因為Qt的編譯系統是通過qmake將.pro 文件轉換成Makefile文件。當qmake掃描.h代碼時發現有Q_OBJECT這樣字眼的代碼時,會將一個用moc生成moc_xxx.cpp代碼 的依賴關系寫到Makefile里。如果掃描時沒有找到Q_OBJECT就不會生成額外的moc_xxx.cpp這樣的文件。

出現最初一幕的原因是在執行qmake的時候.h代碼里並沒有O_OBJECT這樣的代碼。而執行make的時候.h里已經有Q_OBJECT了,解決的方法就是重新執行qmake,然后執行make.

——

shiroki:另外我再加一句, 還有一種可能性是寫代碼的人把所有的代碼都寫在了.cpp文件中。要知道moc工具只讀.h文件,如果把Q_OBJECT宏放在cpp里moc是看不到的……所以大家寫代碼還是要遵守聲明放.h實現放cpp的規矩比較好。

Q_OBJECT undefined reference to 問題  

摘自:http://waiter94.blog.163.com/blog/static/5277376920103423144138/

如果你的class的定義和身明 是放在同一cpp文件里 如: Test.cpp, 並且在class使用了slot/signal. 在這個cpp文件的最底部 加上

#include "文件名.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,從而形成信號接力.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM