2013-01-11 118 views
3

可能重複:
Qt: Signals and slots Error: undefined reference to `vtable forQt「hello world」GUI應用程序沒有鏈接?

在這裏,我們有TEST.CPP:單獨

#include <QApplication> 
#include <QMainWindow> 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 
}; 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 

放置在一個新的目錄:

$ qmake -project 
$ qmake 
$ make 

它不工作:

test.o: In function `MainWindow::~MainWindow()': 
test.cpp:(.text._ZN10MainWindowD2Ev[_ZN10MainWindowD5Ev]+0x3): undefined reference to `vtable for MainWindow' 
test.cpp:(.text._ZN10MainWindowD2Ev[_ZN10MainWindowD5Ev]+0xb): undefined reference to `vtable for MainWindow' 
test.o: In function `main': 
test.cpp:(.text.startup+0x48): undefined reference to `vtable for MainWindow' 
test.cpp:(.text.startup+0x51): undefined reference to `vtable for MainWindow' 
test.o: In function `MainWindow::~MainWindow()': 
test.cpp:(.text._ZN10MainWindowD0Ev[_ZN10MainWindowD0Ev]+0x7): undefined reference to `vtable for MainWindow' 
test.o:test.cpp:(.text._ZN10MainWindowD0Ev[_ZN10MainWindowD0Ev]+0xf): more undefined references to `vtable for MainWindow' follow 
collect2: error: ld returned 1 exit status 
make: *** [tmp] Error 1 

一般來說這樣的錯誤是因爲建設部是不會調用或因未實現的虛方法。

moc應該由qmake自動調用,並且afaik QMainWindow沒有任何純虛方法 - 那麼這裏有什麼問題?

當我刪除Q_OBJECT它的作品。爲什麼是這樣?到底是怎麼回事?

我看到Q_OBJECT告訴moc爲該對象生成信號/槽元數據,爲什麼在這種情況下不能這樣做呢?

更新:

解決方法是僅低於類添加#include "test.moc"

#include <QApplication> 
#include <QMainWindow> 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 
}; 

#include "test.moc" // <----------- HERE 

int main(int argc, char *argv[]) 
{ 
    QApplication a(argc, argv); 
    MainWindow w; 
    w.show(); 

    return a.exec(); 
} 
+0

一旦你把Q_OBJECT到那裏,你必須「MOC」的文件;將類聲明移動到'.h'允許生成器完成所有這些基礎工作。否則,當您在.cpp中聲明所有內容時,必須手動('moc').cpp文件並將生成的.cpp文件包含在源代碼或依賴項中的某處。 – dans3itz

+0

@ dans3itz:有沒有辦法告訴pro文件我想cpp moced?我想在cpp文件中有類定義。 –

+0

@Andrew:當然你可以把你的def放在你想要的位置 - 但我建議你把它們放在一個單獨的.h文件中,並且不加修改地使用Qt。將類的分離與其定義分開是很好的做法,你應該有很好的理由不這樣做。 – Zane

回答

10

這是因爲你聲明的.cpp文件中的類。把它放在一個單獨的.h頭文件中。

默認情況下,不會爲源文件調用MOC,僅用於標題(編輯:根據@Kamil,MOC針對.cpp源文件運行,但生成的.moc文件應手動輸入爲#include -d .cpp文件 - 請參閱下面的編輯)。

然後,將相應的頭文件添加到.pro文件中的HEADERS變量。

當然,#include將相同的頭文件放入test.cpp。

而且,看到這個答案在這裏:

https://stackoverflow.com/a/5854884/1284631

編輯:

根據這個線索:http://www.qtcentre.org/threads/28580-Why-does-qmake-moc-only-process-header-files

強制MOC運行.cpp文件,你應該增加:

#include "test.moc"

正好在你的班級的定義之下。然後重新運行qmake。但是,我沒有測試這個。

EDIT2:請參閱就行了討論這個參考什麼OP是尋找:

http://harmattan-dev.nokia.com/docs/library/html/qt4/moc.html

+0

有沒有辦法告訴pro文件我想cpp moced而不移動到一個單獨的頭文件?我故意要使用一個cpp。 –

+0

嘗試將其添加到HEADERS變量:HEADERS + = test.cpp。我認爲您還需要在test.cpp文件的末尾添加#include「moc_test.cpp」(moc_文件是由MOC生成的文件)。但是,這個解決方案很麻煩。 – user1284631

+0

錯誤:默認情況下,即使對於.cpp文件也調用MOC,但是您必須在.cpp文件中包含filename.moc文件 –