Архитектура для спокойного СИГНАЛА с определенным для подкласса, шаблонным типом аргумента

Я разрабатываю приложение приобретения научных данных с помощью QT, Так как я не глубокий эксперт в QT, я хотел бы некоторую архитектуру, консультируют от сообщества по вопросам следующей проблемы:

Поддержка приложений несколько интерфейсов приобретения оборудования, но я хотел бы обеспечить общий API сверху тех интерфейсов. Каждый интерфейс имеет демонстрационный тип данных и единицы для его данных. Таким образом, я представляю вектор образцов от каждого устройства как a std::vector из Повышения. Количества единиц (т.е. std::vector<boost::units::quantity<unit,sample_type> >). Я хотел бы использовать многоадресную архитектуру стиля, где каждый источник данных широковещательные сообщения недавно получил данные к 1 или более заинтересованные стороны. Механизм Сигнала/Слота QT является очевидным пригодным для этого стиля. Так, я хотел бы, чтобы каждый источник данных испустил сигнал как

typedef std::vector<boost::units::quantity<unit,sample_type> > SampleVector
signals:
    void samplesAcquired(SampleVector sampleVector);

для единицы и sample_type подходящий для того устройства. Так как шаблонный QObject подклассы не поддерживаются компилятором метаобъекта, кажется, нет способа иметь (шаблонный) базовый класс для всех источников данных, который определяет samplesAcquired Сигнал. Другими словами, следующее не будет работать:

template<T,U> //sample type and units
class DataSource : public QObject {
  Q_OBJECT
  ...
  public:
    typedef std::vector<boost::units::quantity<U,T> > SampleVector
  signals:
    void samplesAcquired(SampleVector sampleVector);
};

Наилучшим вариантом, который я смог придумать, является двухмногоуровневый подход:

template<T,U> //sample type and units
class IAcquiredSamples {
    public:
        typedef std::vector<boost::units::quantity<U,T> > SampleVector
        virtual shared_ptr<SampleVector> acquiredData(TimeStamp ts, unsigned long nsamples);
};

class DataSource : public QObject {
    ...
    signals:
      void samplesAcquired(TimeStamp ts, unsigned long nsamples);
};

samplesAcquired сигнал теперь дает метку времени и количество образцов для приобретения, и клиенты должны использовать IAcquiredSamples API для получения тех образцов. Очевидно источники данных должны разделить на подклассы и DataSource и IAcquiredSamples.

Недостаток этого подхода, кажется, потеря простоты в API... было бы намного более хорошо, если клиенты могли бы получить полученные образцы в соединенном Слоте. Способность использовать соединения QT с очередями также сделала бы проблемы поточной обработки легче вместо того, чтобы иметь необходимость управлять ими в acquiredData метод в каждом подклассе.

Еще одна возможность, должен использовать a QVariant аргумент. Это обязательно возлагает ответственность на подкласс для регистрации их конкретного демонстрационного типа вектора в Q_REGISTER_METATYPE/qRegisterMetaType. Едва ли грандиозное предприятие. Клиенты базового класса однако, не будет иметь никакого способа знать что тип QVariant тип значения, если структура тега также не передается с сигналом. Я рассматриваю это решение, по крайней мере, как замысловатое как то выше, поскольку это вынуждает клиенты абстрактного базового класса API иметь дело с некоторыми gnarlier аспектами системы типов.

Так, есть ли способ достигнуть шаблонного параметра сигнала? Существует ли лучшая архитектура, чем та, которую я предложил?

9
задан Marc Mutz - mmutz 27 April 2011 в 02:18
поделиться

2 ответа

Существует тип QVariant - вы можете создать на нем свой собственный подтип
и использовать его как параметр (если я поймите свое право и это то, что вы хотите) в сигналах
http://doc.trolltech.com/qq/qq14-metatypes.html#customtypesinqvariant

2
ответ дан 3 November 2019 в 07:13
поделиться

Одним из упрощений вашего двухуровневого подхода было бы использование класса QObject в качестве основы без шаблона для шаблона класса, т. Е. что-то вроде

class DataSourceBase : public QObject {
    Q_OBJECT
    ...
    signals:
      void samplesAcquired(TimeStamp ts, unsigned long nsamples);
};

template<T,U> //sample type and units
class DataSource : public DataSourceBase {
    public:
        typedef std::vector<boost::units::quantity<U,T> > SampleVector
        virtual shared_ptr<SampleVector> acquiredData(TimeStamp ts, unsigned long nsamples);
};

Обратите внимание, что недостатком этого подхода является то, что, поскольку вы не можете использовать макрос Q_OBJECT в шаблоне класса, информация об этом отсутствует в системе метаобъектов Qt.

1
ответ дан 3 November 2019 в 07:13
поделиться
Другие вопросы по тегам:

Похожие вопросы: