Ошибка qt: неопределенная ссылка на `vtable for Thread ' - PullRequest
3 голосов
/ 16 июня 2011

У меня есть код:

#include <iostream>
#include <QThread>
#include <unistd.h>
#include <stdlib.h>
#include <QApplication>


using std::cerr;
using std::endl;

class Thread : public QThread
{
    Q_OBJECT
public:
    Thread();
    ~Thread();
    void setMessage(const QString &_message);
    void stop();
protected:
    void run();
private:
    QString message;
    volatile bool stopped;
};

Thread::Thread()
{
    stopped = false;    
    run();
}

Thread::~Thread()
{

}


void Thread::run()
{
    while(!stopped){
        cerr << qPrintable(message);
        sleep(1);
    }
        stopped = false;
        cerr << endl;
}

void Thread::stop()
{
    stopped = true; 
}

void Thread::setMessage(const QString &_message)
{
    message = _message; 
}

int main(int argc,char *argv[])
{
    QApplication app(argc, argv);
    Thread *A,*B;
    A = new Thread();
    B = new Thread();
    A->setMessage("Thread A\n");
    B->setMessage("Thread B\n");
//.run();
//.run();
    sleep(10);
    A->stop();
    B->stop();
    return 0;
}

и у меня ошибка

g++ -Wl,--hash-style=gnu -Wl,--as-needed -Wl,-O1 -o tmp main.o    -L/usr/lib -lQtGui -lQtCore -lpthread 
main.o: In function `Thread::~Thread()':
main.cpp:(.text+0xa): undefined reference to `vtable for Thread'
main.o: In function `Thread::Thread()':
main.cpp:(.text+0x1da): undefined reference to `vtable for Thread'
collect2: ld returned 1 exit status
make: *** [tmp] Error 1

Ответы [ 4 ]

10 голосов
/ 16 июня 2011

Вы должны создать заголовок с помощью moc. Это можно сделать автоматически с помощью системы сборки Qt. Вместо непосредственного использования gcc, вы должны использовать файл qmake.

Также вам, вероятно, следует разделить объявление и код на файл заголовка и файл cpp.

Вот описание того, что делает moc: http://doc.qt.nokia.com/latest/moc.html

И похожий вопрос (с ответами) здесь на stackoverflow: Неопределенная ссылка на vtable. Попытка скомпилировать проект Qt

6 голосов
/ 16 июня 2011

Вам нужна строка внизу исходного файла:

#include "main.moc"

Это потому, что объявление class Thread находится не в заголовке, а в файле .cpp. По умолчанию moc не будет работать на нем. Добавление строки делает две вещи:

  • сообщает qmake и moc, что moc должен обработать файл .cpp
  • это заставляет материал, который генерируется moc, извлекаться на этапе компиляции

Итак, после добавления этой строки вам нужно будет перезапустить qmake, чтобы он мог обновить make-файлы, чтобы генерировать main.moc.

Обычно moc работает с заголовочными файлами и создает файлы .cpp, которые включаются в сборку (qmake следит за этим). Этот «трюк» заставляет moc также запускаться для файла .cpp в вопросе (и иметь скомпилированный сгенерированный код moc).

Альтернативой включению main.moc в конце main.cpp является перемещение определения class Thread в файл заголовка .h и #include что. Если определение находится в заголовке qmake и moc должны обрабатывать вещи автоматически.

0 голосов
/ 30 мая 2019

Я думаю , что система qmake требует, чтобы ваш заголовочный файл содержал напрямую. Моя не смогла сгенерировать moc, пока я не добавил это.

0 голосов
/ 27 марта 2017

Просто добавьте строку в .pro файл.Это помогло мне в той же проблеме

INSTALLS += target

См. Пример queudcustomtype.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...