undefinedreferenceto`vtablefor出現(xiàn)原因

字號:

由于Qt本身實(shí)現(xiàn)的機(jī)制所限,我們在使用Qt制作某些軟件程序的時候,會遇到各種各樣這樣那樣的問題,而且很多是很難,或者根本找不到原因的,即使解決了問題,如果有人問你為什么,你只能回答--不知道。
    今天考試,大提示在這里列舉的問題也是再編寫Qt程序時,總是遇到的問題,問題普遍,而答案卻不,解釋這一個問題的說法很多,往往只適合某一種情況,因?yàn)檫@個錯誤太籠統(tǒng)了,它就是-- “undefined reference to `vtable for”可能你看著很熟悉,似乎在c++程序中也遇到過這個問題,你說對了,有時候這個錯誤,不只是qt的原因,還有你的c++程序的原因。
    一:
    預(yù)編譯器打開宏Q_OBJECT,聲明若干個由moc處理(implement)的成員函數(shù)。如果得到類似于“undefined reference to vtable for LcdNumber”的編譯錯誤(if you get compiler errors along the lines of "undefined reference to vtable for LcdNumber"),你可能是忘記了執(zhí)行moc,或者忘記了將moc輸出加入到link命令里。
    某一個類中如果加入Q_OBJECT后,則link時提示:undefined reference to vtable for "xxx::xxx".刪掉它則沒有任何問題.
    解決:嘗試(1):把所有的obj文件和uic文件刪除,重新編譯.仍然失敗.
    去trolltech的mail lists找到原因: 因?yàn)閝make生成Makefile的時候,這個類的頭文件中并沒有Q_OBJECT,所以在相應(yīng)的Makefile里面并沒有用moc xxx.h命令,最終導(dǎo)致鏈接失敗.重新運(yùn)行qmake,問題解決.
    在查找解決方法的時候,附帶發(fā)現(xiàn)一點(diǎn):
    qmake 不會處理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的話,也會產(chǎn)生undefined reference to vtable for "xxx::xxx". 這時,需要先用moc xxxx.cpp生成相應(yīng)的moc文件,再包含到.cpp里面去,才能解決這個問題.
    這里可以發(fā)現(xiàn)問題的出現(xiàn)是因?yàn)闆]有moc生成相應(yīng)的moc文件,之后連接就出問題。
    我找了好多源碼之類的問題,就是沒有找pro的錯誤,后來想到qt中moc我們是有make做的
    qt的make編譯是根據(jù)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文件中有它的話,也會產(chǎn)生undefined reference to vtable for "xxx::xxx". 這時,需要先用moc xxxx.cpp生成相應(yīng)的moc文件,再包含到.cpp里面去,才能解決這個問題.
    其他:
    1.問題: QGLViewer中的函數(shù)不能正常link.
    解決: 翻看其源代碼,發(fā)現(xiàn)是因?yàn)閺脑创a安裝libQGLViewer時,編譯用了Qt 3,而我的程序中用Qt4 編譯.所以必須重新用Qt4編譯.但是,更改QTDIR 環(huán)境變量為Qt4后,重新編譯的話,qmake生成makefile時就提示出錯.進(jìn)一步發(fā)現(xiàn),是因?yàn)殡m然設(shè)了QTDIR為Qt4,頭文件和庫文件都會使 用Qt4,但是moc,uic等都是用的qt3版的,再把PATH環(huán)境變量改動后,一切ok.
    2.問題:某一個類中如果加入Q_OBJECT后, 則link時提示:undefined reference to vtable for "xxx::xxx".刪掉它則沒有任何問題.
    解決:嘗試(1):把所有的obj文件和uic文件刪除,重新編譯.仍然失敗.去trolltech的 mail lists找到原因: 因?yàn)閝make生成Makefile的時候,這個類的頭文件中并沒有Q_OBJECT,所以在相應(yīng)的Makefile里面并沒有用moc xxx.h命令,最終導(dǎo)致鏈接失敗.重新運(yùn)行qmake,問題解決.在查找解決方法的時候,附帶發(fā)現(xiàn)一點(diǎn):
    qmake 不會處理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的話,也會產(chǎn)生undefined reference to vtable for "xxx::xxx". 這時,需要先用moc xxxx.cpp生成相應(yīng)的moc文件,再包含到.cpp里面去,才能解決這個問題.
    3. 看Qt的reference發(fā)現(xiàn): 可以connect(pObjA, SIGNAL(someSignalA()),pObjB,SIGNAL(someSignalB()));這樣pObjA發(fā)出的someSingalA 會導(dǎo)致pObjB發(fā)出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 的 方法, 但在實(shí)現(xiàn)(cpp)文件里沒有實(shí)現(xiàn)。
    看了一下, 現(xiàn)在推測一下。 MyPlot 繼承了 QwtPlot, 現(xiàn)在報的這個錯, 應(yīng)該是這個意思,
    1. QwtPlot 里含有 vritual 方法, 所以你的繼承類需要一個 virtual 的析構(gòu)函數(shù)
    2. QwtPlot 里含有 純虛的方法, 你沒有繼承, 而這個可能性比較小
    所以, 你可以:
    在MyPlot里聲明一下一個虛的析構(gòu)函數(shù)
    virtual ~MyPlot() {}我們來看一個簡單些的例子吧:
    CODE:[Copy to clipboard]#include
    #include
    class myWidget :public QWidget
    {
    Q_OBJECT
    public:
    myWidget(QWidget *parent = 0);
    public slots:
    void shutDown();
    private:
    QPushButton *exit;
    };
    myWidget::myWidget(QWidget *parent):QWidget(parent)
    {
    setMinimumSize(120, 180);
    setMaximumSize(120, 180);
    exit = new QPushButton("ShutDown!",this);
    connect(exit,SIGNAL(clicked()),this,SLOT(shutDown()));
    }
    void myWidget::shutDown()
    {
    system("halt");
    }
    int main(int argc, char **argv)
    {
    QApplication app(argc, argv);
    myWidget *w = new myWidget();
    w->show();
    app.exec();
    }
    還是報錯:
    CODE:[Copy to clipboard]shut.o(.text+0x21): In function `myWidget::myWidget[not-in-charge](QWidget*, char const*)’:
    : undefined reference to `vtable for myWidget’
    shut.o(.text+0x28): In function `myWidget::myWidget[not-in-charge](QWidget*, char const*)’:
    : undefined reference to `vtable for myWidget’
    shut.o(.text+0x141): In function `myWidget::myWidget[in-charge](QWidget*, char const*)’:
    : undefined reference to `vtable for myWidget’
    shut.o(.text+0x148): In function `myWidget::myWidget[in-charge](QWidget*, char const*)’:
    : undefined reference to `vtable for myWidget’
    collect2: ld returned 1 exit status
    這是我從l搜索引擎上搜到的例子,從代碼中好像看不到明顯的錯誤吧
    我自己試了一下編譯也是出錯
    剛才那個簡單的例子的原因可能是這樣的:
    QUOTE:
    2.問題:某一個類中如果加入Q_OBJECT后,則link時提示:undefined reference to vtable for "xxx::xxx".刪掉它則沒有任何問題.
    解決:嘗試(1):把所有的obj文件和uic文件刪除,重新編譯.仍然失敗.
    去trolltech的mail lists找到原因: 因?yàn)閝make生成Makefile的時候,這個類的頭文件中并沒有Q_OBJECT,所以在相應(yīng)的Makefile里面并沒有用moc xxx.h命令,最終導(dǎo)致鏈接失敗.重新運(yùn)行qmake,問題解決.
    在查找解決方法的時候,附帶發(fā)現(xiàn)一點(diǎn):
    qmake不會處理.cpp文件里的Q_OBJECT,所以,如果在.cpp文件中有它的話,也會產(chǎn)生undefined reference to vtable for "xxx::xxx". 這時,需要先用moc xxxx.cpp生成相應(yīng)的moc文件,再包含到.cpp里面去,才能解決這個問題.
    知道你的問題了, 上面的例子不好, 因?yàn)槟氵@個把main和類放在一起了。 如果分開, 可能就沒問題, 包括 h和 cpp 分開。
    要解決上面的問題, 在你main.cpp 最后加一行
    #include "main.moc"
    然后把除了 main.cpp 的其它文件都刪了。重新來, 沒問題的。
    所以, 我估計你前面提到的問題也是沒有鏈接 moc 文件。 你在你的 myplot.cpp 文件最后加一行: #include "myplot.moc" 試試看。
    另外: 你main 沒有返回值, 編譯會警告, 而且程序最后一行不是只含有回車, 也會警告。