今天看1+1=2大牛的Qt文章中關於多線程的部分,於是自己想動手實現一下,沒想到遇到這種問題undefinedreferenceto`vtable for 。。。。,蛋疼了一上午,也查了好多資料,那些資料比這個錯誤還難理解,有興趣的請看這裡http://www.examda.com/ncre2/cpp/fudao/20081219/085036477.html。
這個錯誤是在程式中添加了QOBJECT關鍵字以後出現的,但是我忽然想起,自己初學Qt時,按著那本官方教科書第二版寫程式的時候怎麼沒遇到過呢,難道是因為我把所有代碼都寫到main.cpp中的緣故?嗯!就是這樣!
整個解決過程如下:
開始我用Qt建立工程Test:在main.cpp中添加代碼如下:
#include <QCoreApplication>#include <QThread>#include <QDebug>#include <QObject>class LongTimeAct: public QObject{ Q_OBJECTpublic slots: void act();};class Begin:public QObject{ Q_OBJECTsignals: void sig();public: void emiting();};void LongTimeAct::act(){ qDebug()<<"slot---My thread id is :"<<QThread::currentThreadId();}void Begin::emiting(){ qDebug()<<"sig---my thread id is :"<<QThread::currentThreadId(); emit sig();}int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); qDebug()<<"main---my thread id is :"<<QThread::currentThreadId(); QThread thread; LongTimeAct act; Begin begin; act.moveToThread(&thread); QObject::connect(&begin,SIGNAL(sig()),&act,SLOT(act())); thread.start(); begin.emiting(); return a.exec();}
一編譯,便出現了題目中的那個錯誤,如:
於是我便又向工程中添加了一個test.h檔案和一個test.cpp檔案。然後把main.cpp中的代碼分拆到這倆檔案中。
test.h中的代碼如下:
#ifndef TEST_H#define TEST_H#include <QObject>class LongTimeAct: public QObject{ Q_OBJECTpublic slots: void act();};class Begin:public QObject{ Q_OBJECTsignals: void sig();public: void emiting();};#endif // TEST_H
test.cpp中的代碼如下:
#include <QThread>#include <QDebug>#include "test.h"void LongTimeAct::act(){ qDebug()<<"slot---My thread id is :"<<QThread::currentThreadId();}void Begin::emiting(){ qDebug()<<"sig---my thread id is :"<<QThread::currentThreadId(); emit sig();}
main.cpp中的代碼如下:
#include <QCoreApplication>#include <QDebug>#include <QThread>#include "test.h"int main(int argc, char *argv[]){ QCoreApplication a(argc, argv); qDebug()<<"main---my thread id is :"<<QThread::currentThreadId(); QThread thread; LongTimeAct act; Begin begin; act.moveToThread(&thread); QObject::connect(&begin,SIGNAL(sig()),&act,SLOT(act())); thread.start(); begin.emiting(); return a.exec();}編譯以後就成功了!!!!如:
可惜的是我只是解決了這個編譯錯誤,但我不知道為什麼這樣做,因為我查了.pro檔案,發現裡面除了添加了標頭檔和cpp檔案外跟原來沒什麼差別。
望路過的大牛指點一下為什麼這樣子做就可以避免這個編譯錯誤了。不勝感激!
另外還有一點就是我最開始還遇到了collect2:ld returned 1 exit status錯誤,原因就是我文法不熟,我為了在發射訊號時輸出一句話自己定義了Begin類中的sig()函數,這個函數是訊號函數,只能聲明不能自己定義,Qt內部會處理,有關訊號和槽的問題,詳見http://blog.csdn.net/michealtx/article/details/6858784。要把它那句輸出放到發射sig()訊號的emiting()函數中emit
sig();前面,詳見test.cpp中的emiting()函數,如下代碼是錯誤的:
void Begin::sig(){ qDebug()<<"sig---my thread id is :"<<QThread::currentThreadId();}