Meta-object System (Meta-object System)
Мета-объектная система в Qt framework предоставляет поддержку дополнительных возможностей в языке C++, необходимое для интроспекции и рефлексии, предоставляя класс QObject с некоторым функционалом, как базовый. Фактически подавляющее большинство классов в Qt являются наследниками этого класса и реализуют данную систему.[1]
Реализация
[править | править код]Мета-объектная система включает в себя: класс QObject, утилиту moc(Мета-Объектный Компилятор) и необязательный макрос Q_OBJECT.
- QObject является базовым классом для всех классов Qt
- Мета-объектный компилятор предоставляет каждому подклассу QObject необходимый код на C++, для реализации мета-объектных возможностей, с учетом наличия или отсутствия макроса Q_OBJECT. Компилятор, не изменяет исходный файл, а создает другой содержащий метаобъектный код для каждого из этих классов.
- Макрос Q_OBJECT необходим мета-объектному компилятору. Находя данный макрос в исходном коде, компилятор объявляет некоторые функции, которые необходимы для анализа внутреннего состояния и должны быть реализованы в каждом подклассе QObject: metaObject(), tr(), qt_metacall() и некоторые другие.[2]
Допустимо использовать QObject в качестве базового класса и без макроса Q_OBJECT и без мета-объектного кода. Однако в таком случае, ни сигналы и слоты, ни другие возможности, описанные ниже, не будут доступны. С точки зрения метаобъектной системы, подкласс QObject без мета-кода аналогичен своему ближайшему предку с мета-объектным кодом. Это означает, что QMetaObject :: className () вернет не фактическое имя вашего класса, а имя класса этого предка.
Макросы, используемые Мета-Объектным компилятором для аннотации кода — это стандартные макросы C++. Они должны быть корректно распознаны любым инструментом, способным анализировать код на C++. Добавляя макрос Q_OBJECT, программист дописывает объявление нескольких функций.
Класс QObject, при наличии макроса Q_OBJECT содержит в себе поддержку:
- Метаобъектной информации. Она включает в себя информацию о наследовании классов, что позволяет определять являются ли классы непосредственными наследниками, а так же узнать имя класса. Предоставляется и информация о мета-методах класса (сигналах, слотах и других вызывающихся функциях с макросом Q_INVOKABLE).
- Динамического приведения типов с помощью qobject_cast () для классов QObject . Функция qobject_cast () ведет себя аналогично стандартной C ++
dynamic_cast()
с теми преимуществами, что она не требует поддержки RTTI и работает через границы динамических библиотек. Функция пытается привести свой аргумент к типу указателя, указанному в угловых скобках, возвращая ненулевой указатель, если объект имеет правильный тип (определенный во время выполнения), илиnullptr
, если тип объекта несовместим. - Таймера, и соответственно цикл обработки событий. Дополнительно имеется механизм фильтрации, для перехвата данных событий.
- Возможность интернационализации приложения с помощью методов QObject::tr() и QObject::trUtf8().
- Поддержку сигналов и слотов , которые используются для связи между слабо-связанными объектами.
- Поддержка свойств, для получения информации об объектах Qt, не из C++ кода, например из QML или Qt Script.
Использование мета-объектных систем прошло через некоторую критику. В документации Qt было дано несколько аргументов в пользу мета-объектных систем, включая плюсы генерации кода, динамичности графических интерфейсов, автоматической связи со скриптовыми языками, не добавляя ограничений и так же хорошая, производительность механизма сигналов и слотов в moc.[3] [4]
Ссылки
[править | править код]- ↑ The Meta-Object System - QtCore 5.1 . Qt Project (4 июля 2013). Дата обращения: 4 июля 2013. Архивировано 26 августа 2013 года.
- ↑ Using the Meta-Object Compiler (moc) . Qt Project (4 июля 2013). Дата обращения: 4 июля 2013. Архивировано 26 августа 2013 года.
- ↑ Why Does Qt Use Moc for Signals and Slots? Qt Project (4 июля 2013). Дата обращения: 4 июля 2013. Архивировано 20 октября 2013 года.
- ↑ Re-implementing Qt moc using libclang . Olivier Goffart (4 июля 2013). Дата обращения: 4 июля 2013. Архивировано 15 июля 2013 года.