1. 程式人生 > >undefinedreferenceto`vtablefor出現原因我這裡的一個答案

undefinedreferenceto`vtablefor出現原因我這裡的一個答案

由於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"
  原 因: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,從而形成訊號接力.
  from:http://blog.donews.com/netexe/archive/2006/02/09/720544.aspx
三:
  編譯報錯的部分是:
  CODE:[Copy to clipboard]tmp\obj\release_shared\myplot.o(.text+0x194):myplot.cpp: undefined reference to
  `vtable for MyPlot’
  tmp\obj\release_shared\myplot.o(.text+0x19b):myplot.cpp: undefined reference to
  `vtable for MyPlot’
  tmp\obj\release_shared\myplot.o(.text+0x934):myplot.cpp: undefined reference to
  `vtable for MyPlot’
  tmp\obj\release_shared\myplot.o(.text+0x93b):myplot.cpp: undefined reference to
  `vtable for MyPlot’
  collect2: ld returned 1 exit status
  你 MyPlot 是不是聲明瞭什麼 virtual 的 方法, 但在實現(cpp)檔案裡沒有實現。
  看了一下, 現在推測一下。 MyPlot 繼承了 QwtPlot, 現在報的這個錯, 應該是這個意思,
  1. QwtPlot 裡含有 vritual 方法, 所以你的繼承類需要一個 virtual 的解構函式
  2. QwtPlot 裡含有 純虛的方法, 你沒有繼承, 而這個可能性比較小
  所以, 你可以:
  在MyPlot裡宣告一下一個虛的解構函式
  virtual ~MyPlot() {}