Является ли мета-система Qt действительно такой утомительной?

Я хотел бы использовать механизм отражения Qt, поскольку в C ++ этой функции нет. Кажется, это работает, но вызов всех макросов и вспомогательных функций очень утомителен. Например, чтобы зарегистрировать перечисление как правильный метатип, мне пришлось пройти все следующие шаги:

  1. Объявите enum внутри класса-обертки, который содержит Q_GADGET макро.
  2. Зарегистрируйте перечисление, используя Q_ENUM макрос сразу после этого.
  3. Зарегистрируйте класс, содержащий перечисление: Q_DECLARE_METATYPE(MyClass)
  4. Вызов qRegisterMetaType<..>() для типа класса упаковки и
    за каждое объявленное перечисление.

Теперь я знаю, что некоторые из шагов могут быть пропущены, если часть полной функциональности не требуется. Но это не то, что я ищу, мне нужно использовать перечисления внутри сигналов, и мне нужно иметь возможность получить мета-метод сигнала и запросить его для его типа параметров.

Но все же я не могу не думать, что должен быть лучший / более простой способ сделать это.

2

Решение

К сожалению, вы не можете сделать меньше, чем это.

  • Q_GADGET (или же Q_OBJECT, для подклассов QObject) означает «генерировать мета-объектную информацию для этого класса».
  • Q_ENUM означает «генерировать мета-перечисление информации для этого конкретного перечисления». Теперь можно утверждать, что все (публичные?) Перечисления в зарегистрированном классе также должны быть автоматически зарегистрированы. Но так как это имеет стоимость (двоичный размер), и мы используем C ++, мы не хотим платить за перечисления, которые мы никогда не собираемся использовать в мета-объектной системе, так что это опция.
  • Q_DECLARE_METATYPE (не требуется для самого перечисления, если вы используете Q_ENUM; не требуется в общем случае в вашем сценарии) позволяет использовать тип внутри QVariants (Q ++ C ++ 98, RTTI-менее воплощение C ++ 17 std::any). Хотите вы этого или нет, зависит от типа. Я бы сказал, что все «типы значений» должны иметь его, но опять же, это генерирует дополнительный код, за который вы, возможно, не захотите платить. Кроме того, это действительно относится только к «типам значений» — эта регистрация требует, чтобы тип имел общедоступный конструктор по умолчанию, общедоступный конструктор копирования, общедоступное назначение копирования, публичный деструктор. Если у вас есть класс, у которого его нет, вы не можете использовать этот макрос => вы не можете обернуть его в QVariant,
  • qRegisterMetaType регистрирует вышеупомянутые конструкторы / деструкторы в таблице во время выполнения, позволяя вам иметь уникальный идентификатор для типа (требуется, если вы хотите идентифицировать типы в сигнатурах методов), динамически создавать или уничтожать экземпляры типа (требуются, среди прочего, для реализации соединений в очереди: Qt нужен общий способ скопировать аргументы сигнала в событие, которое будет отправлено в целевой поток, и уничтожить такие аргументы позже), используйте подсистему Q_PROPERTY.

В зависимости от того, что именно вам нужно сделать, вам нужно подмножество всего этого.

6

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]