[C++] Виртуальный сигнал Qt?


Answers

Строго говоря, на C ++ это нормально, он компилируется, данный signal является макросом для protected а Q_UNUSED - Q_UNUSED . Но вы должны получить сообщение об ошибке при запуске moc который точно создает реализацию методов, объявленных как сигналы.

Question

При просмотре кода Qt C ++ я столкнулся с этим:

class Foo
{
  Q_OBJECT

signals:
  virtual void someSignal(const QString& str, int n)
  {
    Q_UNUSED(str);
    Q_UNUSED(n);
  }
  ...
};

Теперь, сигналы Qt не могут иметь тело, поэтому я удивлен, что это даже компилируется (возможно, потому, что тело эффективно пуст). Я также не вижу смысла делать сигнал виртуальным, поскольку ... он не может иметь тело, так как его можно переопределить?

Я что-то пропустил здесь или это действительный запах кода?




TL; DR: Я не знаю, что должен был делать код, но это неправильно (не просто пахнущий неправильно, это prima facie недействительно). Реализации сигналов всегда должны генерироваться moc. Тело сигнала должно быть удалено.

  1. Чтобы код работал, он должен делать все три: компилировать, получать moc и ссылку. Это правда, что ваш код компилируется - у компилятора C ++ нет причин не делать этого. Но он не пройдет через moc и не свяжет его.

  2. Хотя, возможно, moc не обнаружил некоторые из них еще в 2010 году, вот как работает moc сегодня:

    a) moc не допускает определения сигналов в телах классов, с диагностической Error: Not a signal declaration . Итак, class X { Q_SIGNAL void s() {} }; запускает его, но class X { Q_SIGNAL void s(); }; void X::s() {} class X { Q_SIGNAL void s(); }; void X::s() {} class X { Q_SIGNAL void s(); }; void X::s() {} не будет.

    b) moc не допускает макрос Q_OBJECT в классе, не являющемся результатом QObject , с диагностикой Error: Class contains Q_OBJECT macro but does not inherit from QObject .

  3. Поскольку нет смысла говорить о сигналах в классах, которые не выводятся из QObject , давайте предположим, что код действительно выглядел следующим образом:

    class Foo : public QObject
    {
      Q_OBJECT
    signals:
      virtual void someSignal(const QString&, int);
    };
    void Foo::someSignal(const QString& str, int n)
    {
      Q_UNUSED(str);
      Q_UNUSED(n);
    }

    Это пройдет мимо moc и будет скомпилировано, но оно не будет связываться. Foo::someSignal выдает диагностику для множественного объявления Foo::someSignal . В этом файле есть одно определение, другое - в источнике, создаваемом moc.