Qt и нет файла moc_*.cpp

Я разрабатываю простое приложение Qt 4 и создаю свой собственный диалог. Я создал подкласс QDialog, вставил макрос Q_OBJECT в блок объявления класса и...

[Ошибка компоновщика] неопределенная ссылка на `vtable for MyDialog', и moc_MyDialog.cpp не сгенерирован компилятором moc.

Я использую Qt 4.1.3 в Windows XP и mingw. Я следил за процессом сборки из поставляемой Qt оболочки сборки. Я использовал qmake для создания make-файлов и скомпилировал все с помощью команды make.

У меня есть другие классы, которые являются подклассами QPushButton и QObject соответственно, но они компилируются нормально. Я не могу найти никаких отличий между ними и сломанным.

Должно быть, в сломанном классе чего-то не хватает, но я не могу этого обнаружить.


person Łukasz Bownik    schedule 07.10.2008    source источник


Ответы (6)


Неопределенная ссылка на "vtable for MyDialog" вызвана отсутствием файла moc. Большинство компиляторов C++ создают определение vtable в объектном файле, содержащем первую виртуальную функцию. При создании подкласса объекта qt и использовании макроса Q_OBJECT это будет в файле moc*.cpp. Следовательно, эта ошибка означает, что файл moc отсутствует.

Возможные проблемы, о которых я могу думать, следующие:

  1. Файл заголовка для класса MyDialog.h не добавляется в HEADERS в файле qmake.

  2. Вы запустили qmake для создания make-файла перед добавлением макроса Q_OBJECT. Это создало файл make без правил moc. Это легко исправить, просто снова запустив qmake.

  3. Ваш диалог происходит от более чем одного класса, и QDialog не является первым классом, от которого он происходит. Чтобы qmake работал правильно, производный от QObject базовый класс должен быть первым классом, от которого наследуется.

  4. Если вы используете Qt Creator, вы можете получить эту ошибку, если ваше предыдущее развертывание не удалось по какой-либо причине (например, приложение уже запущено). В этом случае просто выполните «Чистый проект», затем «Перестроить проект», а затем «Выполнить» для развертывания.

person David Dibben    schedule 07.10.2008
comment
Я столкнулся с этим по другой причине: 5. Путь к файлу слишком длинный. Я столкнулся с этим в основном в Windows, где некоторая часть системы сборки ограничена древним ограничением Windows в 255 символов. - person Viktor Benei; 20.05.2012
comment
Кроме того: отсутствие QT += gui в файле .pro дает мне такое поведение с Qt 4.7.4. - person mlvljr; 13.07.2012
comment
qmake ищет заголовки только в текущем каталоге, поэтому, если заголовок находится в другом каталоге, вы должны указать полный путь в HEADERS. - person Remi; 12.10.2012
comment
там должен быть полный путь, например: HEADERS += src/*.h не будет работать, вам нужны HEADERS += src/metafile.h - person RzR; 17.05.2014

Если у вас есть заголовочный файл, выполните следующие действия:

  1. Щелкните правой кнопкой мыши проект, в который вы добавили это.
  2. Нажмите «Выполнить qmake».

Это очистит старые ссылки и создаст макрос Q_OBJECT. QT не делает этого при перестройке.

person Kamrul    schedule 17.05.2012

Я вижу, что проблема возникает только тогда, когда добавляется класс без расширения, а затем расширение добавляется вручную.

Чтобы решить эту проблему, я поместил Q_OBJECT в .h класса, а затем щелкнул правой кнопкой мыши «Источники» -> «Добавить существующие файлы ...», выбрав .ccp моего измененного класса.

person Bemipefe    schedule 06.06.2012

Вы используете qmake? Возможно, вы не добавили его в свой файл .cpp в свои SOURCES и файл .h в свою переменную HEADERS в файле qmake?

person user24560    schedule 07.10.2008

Я скромно предлагаю вам использовать CMake для создания программ Qt в Windows. Это поможет вам не забыть добавить соответствующие файлы в файлы сборки.

Дополнительным преимуществом является то, что вы можете создавать из него файлы сборки make/nmake, файлы решений Visual Studio. И если вы скомпилируете Qt из исходного кода для Visual Studio, вы сможете как кодировать, так и собирать с помощью MS IDE/компилятора.

Это, конечно, если вы вообще используете Visual Studio.

person Marcin Gil    schedule 08.10.2008

Неопределенная ссылка сообщения на `vtable for MyDialog' также может быть результатом отсутствия реализации (в MyDialog) чисто виртуальной функции в классе, производным от которого является MyDialog.

person jelle foks    schedule 11.03.2013