#c #qt #qobject
#qt #vtable #qobject
Вопрос:
Я не могу создать это с ошибкой «неопределенная ссылка на vtable для CustomUndoStack»
Вот код:
class CustomUndoStack : public QObject
{
Q_OBJECT
public:
};
int main(int argc, char *argv[])
{
QCoreApplication qCoreApplication(argc, argv);
CustomUndoStack uStack;
return qCoreApplication.exec();
}
Вот файл .pro:
QT = widgets
CONFIG = c 14 console
CONFIG -= app_bundle
DEFINES = QT_DEPRECATED_WARNINGS
SOURCES = main.cpp
Я вручную удалил каталог сборки, я пробовал «Очистить все» и «Перестроить все» всеми возможными способами, я запускал qmake 100500 раз, я менял пользовательский интерфейс poststack более 9000 раз, но ничего не помогает.
В чем проблема?
UPD, чтобы ответить на комментарий: если я удалю строку Q_OBJECT, я не смогу этого сделать. В нем говорится, что «Нет такого сигнала QObject::undoSignal()»
class CustomUndoStack : public QObject
{
// Q_OBJECT
public:
CustomUndoStack() {
connect(this, SIGNAL(undo_signal()), amp;undoStack, SLOT(undo()));
}
signals:
void undo_signal();
private:
QUndoStack undoStack;
};
Комментарии:
1. Кстати, я использую Qt 5.9
Ответ №1:
Ваша проблема вызвана тем фактом, что у вас есть объявление подкласса класса QObject
и наличие Q_OBJECT
макроса внутри него в .cpp
файле; Этот макрос содержит, среди прочего, объявление виртуального метода:
virtual const QMetaObject *metaObject() const;
qmake
инструмент обрабатывает только файлы заголовков, чтобы найти QObject
подклассы, содержащие Q_OBJECT
макрос, для автоматической генерации фактического кода, соответствующего объявлениям, созданным Q_OBJECT
макросом. В вашем случае qmake
не обрабатывает main.cpp
файл и, следовательно, он остается содержащим нереализованную виртуальную функцию — отсюда и ошибка компоновщика, которую вы получаете.
Правильное решение — переместить объявление класса в отдельный файл заголовка и добавить заголовок в ваш проект. Есть, однако, другое решение, которое является своего рода хакерским, но его можно использовать, если вам по какой-то причине абсолютно необходимо оставить объявление вашего класса внутри .cpp
файла:
class CustomUndoStack : public QObject
{
Q_OBJECT
public:
CustomUndoStack(QObject * parent = 0) : QObject(parent) {}
};
#include "main.moc"
int main(int argc, char *argv[])
{
QCoreApplication qCoreApplication(argc, argv);
CustomUndoStack uStack;
return qCoreApplication.exec();
}
Обратите внимание на #include "main.moc"
линию. Наличие этой строки заставляет qmake
фактически обрабатывать объявления из вашего .cpp
файла и генерировать требуемый .moc
файл, который содержит автоматически сгенерированный код, соответствующий объявлениям, созданным Q_OBJECT
макрокомандой.