Неопределенная ссылка на vtable. Попытка скомпилировать проект Qt
Я использую Code:: Blocks 8.02 и компилятор mingw 5.1.6. Я получаю эту ошибку при компиляции моего проекта Qt:
C: \ Documents and Settings \ The Fuzz \ Desktop \ GUI \ App_interface.cpp | 33 | неопределенная ссылка на `vtable for AddressBook'
Файл AddressBook.h:
#ifndef ADDRESSBOOK_H
#define ADDRESSBOOK_H
#include <QWidget>
class QLabel;
class QLineEdit;
class QTextEdit;
class AddressBook : public QWidget
{
Q_OBJECT
public:
AddressBook(QWidget *parent = 0);
private:
QLineEdit *nameLine;
QTextEdit *addressText;
};
#endif
Файл AddressBook.cpp:
#include <QtGui>
#include "addressbook.h"
AddressBook::AddressBook(QWidget *parent)
: QWidget(parent)
{
QLabel *nameLabel = new QLabel(tr("Name:"));
nameLine = new QLineEdit;
QLabel *addressLabel = new QLabel(tr("Address:"));
addressText = new QTextEdit;
QGridLayout *mainLayout = new QGridLayout;
mainLayout->addWidget(nameLabel, 0, 0);
mainLayout->addWidget(nameLine, 0, 1);
mainLayout->addWidget(addressLabel, 1, 0, Qt::AlignTop);
mainLayout->addWidget(addressText, 1, 1);
setLayout(mainLayout);
setWindowTitle(tr("Simple Address Book"));
}
21 ответ
Предупреждение: не делайте этого, если у вас уже есть файл.pro - вы потеряете его!
Чтобы автоматически гарантировать, что все файлы moc cpp сгенерированы, вы можете заставить qmake автоматически сгенерировать файл.pro для вас вместо того, чтобы писать его самостоятельно.
Бежать
qmake -project
в каталоге проекта, и qmake просканирует ваш каталог на наличие всех заголовков C++ и исходных файлов, чтобы сгенерировать файлы moc cpp.
При использовании Qt Creator:
- Построить → Запустить qmake
- Build → Rebuild All
Проблема почти наверняка заключается в том, что вы не компилируете или не создаете ссылки в сгенерированном файле moc_AddressBook.cpp. (Это должно было быть сгенерировано для вас - вы используете Qt's moc
в вашем коде перед компиляцией, верно?)
Чтобы ответить чуть более подробно, Q_OBJECT
макросигналы Qt's moc
инструмент для создания дополнительного файла реализации, который содержит код, необходимый для поддержки QObject
Метаинформационная система. Если бы у вас были какие-либо сигналы или слоты, он бы тоже кое-что сделал для них.
Альтернативным решением может быть удаление Q_OBJECT
макро. Вы, вероятно, не хотите этого делать, но это помогло бы решить проблему, и это не является строго обязательным для представленного вами кода.
Также я бы отметил, что ваша строка:
#include "addressbook.h"
Вероятно, должно быть:
#include "AddressBook.h"
на основе того, как вы представили имена файлов в вопросе.
Предполагая, что вы используете qmake для генерации вашего Makefile, убедитесь, что AddressBook.h указан в переменной HEADERS вашего файла.pro, например
HEADERS = AddressBook.h
Для проектов CMake, установите CMAKE_AUTOMOC в ON, это решило мою проблему.
#Find includes in corresponding build directories
set(CMAKE_INCLUDE_CURRENT_DIR ON)
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
Я получил это при использовании чисто виртуальных функций. Например, "виртуальный процесс void ();" выдал эту ошибку, в то время как "virtual void process() = 0;" заставил это уйти. Для тех, кто ищет эту проблему, сначала проверьте это. Я использую Netbeans с компилятором MinGW.
Я столкнулся с той же проблемой, используя CLion, и решил ее, добавив эти строки в CMakeLists.txt.
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)
См. https://www.jetbrains.com/help/clion/qt-tutorial.html#qt-setup-in-clion.
Удалил папку сборки, перезапустил Qt Creator и все заработало
У меня была та же проблема, но как только я определил свой конструктор в файле заголовка вместо.cpp, ошибка исчезла. Также соответствующий файл moc отсутствовал в файловой системе и в разделе Makefile "compiler_moc_header_make_all" . Я запустил qmake, и, наконец, все сложилось удачно. Я пошел, чтобы проверить Makefile, и он был там сейчас.
У меня была такая же проблема при попытке использовать защищенную виртуальную функцию. Две вещи работали.
- изменения
void process();
вvoid process() = 0;
- Изготовление
process()
публичный вместо частного
Одна из причин - когда вы объявляете виртуальные функции в классе и не определяете их тело.
Просто Run qmake
для вашего проекта. Это можно легко сделать, щелкнув правой кнопкой мыши на названии вашего проекта и нажав на Run qmake
,
Я прихожу к той же проблеме, перестроить проект никогда не обновлять Makefile, я удаляю Makefile и перестраивать, проблема исчезла. ps: запустить 'make' из командной строки может дать вам более подробную информацию, чем в IDE, и помочь решить реальную проблему.
В моем случае Rebuild All было недостаточно, мне пришлось удалить каталог сборки и сделать Rebuild All - тогда все заработало!
CMake
при использовании CMake, что интересно, если мои файлы .cpp и .h не находятся в одной папке, moc, по умолчанию, не может создать метафайл :)
Заголовочные файлы для компиляции moc должны содержаться в переменной HEADERS += ...:
Я переместил файлы заголовков в Myproject.pro в раздел SOURCES += ..., потому что я хочу, чтобы mySource.h и mySource.cpp были в одном элементе дерева. Но это ошибочно для QT Creator. В результате произошла ошибка "Неопределенная ссылка на vtable". Кажется, что: QT обнаруживает заголовок для компиляции moc только в разделе HEADERS += ... (или переменной). См. Также правильное объяснение в другом ответе stackru. Второй ответ: "Я видел много способов решения проблемы, но нет объяснения, почему это происходит, так что здесь". На мой взгляд, это точное объяснение проблемы, которая помогла мне найти и решить мою проблему.
Перейдите в файл.pro и убедитесь, что в файле.h есть "include" перед ним. HEADERS += include/file.h \ include/file2.h
большинство ошибок из-за использования Q_OBJECT, но не создает файл
moc файл moc определяет
classname::metaObject
staticMetaObject
qt_metacall
Вот пример:
когда источник или заголовок используют Q_OBJECT
/opt/qt/bin/moc ./window.h -o ./moc_window.cpp
Makefile добавить moc_window.o в OBJS
Пример: OBJS=main.o window.o moc_window.o
попробуйте этот источник
https://www.mediafire.com/file/anjeah1jmm07mfe/qt_group_box.tar.gz
см . http://fatalfeel.blogspot.com/2013/11/qt5-c-building.html
Вы получите то же сообщение об ошибке, если случайно добавите прототип деструктора. Добавьте пустое определение деструктора или удалите прототип.
Я использую Qt Creator для компиляции и запуска своих программ, я не часто использую командную строку Qt. Одна вещь, которую я сделал, чтобы избавиться от надоедливой ошибки "vtable что-то что-то", это добавив следующие строки в .pro
файл.
ШАБЛОН = приложение
QT += ядро