Я только начал использовать Qt и заметил, что все определения класса примера имеют макрос Q_OBJECT
в качестве первой строки. Какова цель этого макроса препроцессора?
Что делает макрос Q_OBJECT? Почему все объекты Qt нуждаются в этом макросе?
Ответ 1
Из Документация Qt:
Компилятор метаобъектов, moc, является программа, которая обрабатывает Qt С++ расширения.
Средство moc считывает заголовочный файл С++. Если он найдет один или несколько классов объявления, содержащие Q_OBJECT макрос, он создает исходный файл на С++ содержащий метаобъектный код для эти классы. Среди прочего, метаобъектный код необходим для сигналов и слотов, информацию о времени выполнения и динамическая система свойств.
Ответ 2
Он просто сообщает предкомпилятору, что этот класс имеет элементы gui и должен быть запущен через "moc", вам нужно только добавить это к классам, использующим механизм сигнала/слота.
Но это будет спокойно игнорироваться в любых других классах - это просто добавляет к времени сборки.
Ответ 3
MOC (компилятор метаобъектов) преобразует заголовочные файлы с включенным макросом Q_OBJECT в исходный код С++. Он в основном управляет механизмом сигнального слота и делает его понятным для компилятора С++
Ответ 4
1 Из документации Qt Мета-объектной системы
Инструмент moc читает исходный файл C++. Если он находит одно или несколько объявлений классов, которые содержат макрос Q_OBJECT, он создает другой исходный файл C++, который содержит код мета-объекта для каждого из этих классов. Этот сгенерированный исходный файл либо # include'd в исходный файл класса, либо, чаще всего, компилируется и связывается с реализацией класса.
2 Из документации Qt по THE Q_OBJECT
Макрос Q_OBJECT должен появляться в закрытом разделе определения класса, который объявляет свои собственные сигналы и слоты или использует другие сервисы, предоставляемые мета-объектной системой Qt.
3 Из документации Qt по moc
Инструмент moc читает заголовочный файл C++. Если он находит одно или несколько объявлений классов, которые содержат макрос Q_OBJECT, он создает исходный файл C++, содержащий код мета-объекта для этих классов. Помимо прочего, мета-объектный код требуется для механизма сигналов и слотов, информации о типах во время выполнения и системы динамических свойств.
4 Из документации Qt Сигналы и слоты
Макрос Q_OBJECT расширяется препроцессором для объявления нескольких функций-членов, которые реализованы в moc; если вы получаете ошибки компилятора в соответствии с "неопределенной ссылкой на vtable для LcdNumber", вы, вероятно, забыли запустить moc или включить вывод moc в команду link.
Ответ 5
Маска Q_OBJECT должна появиться в приватном разделе определения класса, который объявляет свои собственные сигналы и слоты или использует другие службы, предоставляемые системой метаобъектов Qt.
Ответ 6
В gcc с -E
вы можете видеть расширенные макросы. Это то, что Q_OBJECT
распространяется на gcc в Linux. Помните, что это может зависеть от платформы и может меняться в зависимости от версии QT. Вы можете видеть, что это не просто тег для компилятора moc.
# 11 "mainwindow.hh"
#pragma GCC diagnostic push
# 11 "mainwindow.hh"
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wsuggest-override"
# 11 "mainwindow.hh"
static const QMetaObject staticMetaObject; virtual const QMetaObject *metaObject() const; virtual void *qt_metacast(const char *); virtual int qt_metacall(QMetaObject::Call, int, void **); static inline QString tr(const char *s, cons
t char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } __attribute__ ((__deprecated__)) static inline QString trUtf8(const char *s, const char *c = nullptr, int n = -1) { return staticMetaObject.tr(s, c, n); } private:
# 11 "mainwindow.hh"
#pragma GCC diagnostic ignored "-Wattributes"
# 11 "mainwindow.hh"
__attribute__((visibility("hidden"))) static void qt_static_metacall(QObject *, QMetaObject::Call, int, void **);
# 11 "mainwindow.hh"
#pragma GCC diagnostic pop
# 11 "mainwindow.hh"
struct QPrivateSignal {};