2017-02-17 4 views
0

Скажем, у меня есть классРазоблачение внутренний компонент класса для того, чтобы предотвратить писать слишком много кода и влияние на производительность

class B : public class QObject { 
    Q_OBJECT 
public: 
    B(QObject* parent=Q_NULLPTR); 
signals: 
    void signalData(int data); 
public slots: 
    void slotGetData(); 
private: 
} 

slotGetData() срабатывает внешне, так и в основном получает некоторые данные из где-то и отправляет его обратно используя signalData(int data). С другой стороны, у меня есть еще один класс

class A : public class QObject { 
    Q_OBJECT 
public: 
    A(QObject* parent=Q_NULLPTR) { 
    // Init B, move to thread, setup timer, connect timer's timeout to B's slotGetData() 

    // Connect B to A 
    connect(this->B, SIGNAL(signalData(int)), this, SLOT(slotGetData(int))); 
    } 
signals: 
    // Emit signal containing data to another Qt component 
    void signalData(int x); 
private slots: 
    // Connect B::signalData(int x) to this slot and re-emit the data using A::signalData(int x). Don't do anything with the data! 
    void slotGetData(int x); 
private: 
    B* workerObj; 
    QThread worker; 
    QTimer workerTimer; 
} 

, который в основном отвечает за инстанцирование workerObj, перемещая его worker нити и присоединительных timeout() сигнала workerTimer «s к B::slotGetData().

Цель этого класса заключается в обеспечении надлежащей интеграции (многопоточный) из B внутри класса третьей стороной, которая хочет использовать его, например:

class ThirdParty : public class QWidget { 
    Q_OBJECT 
public: 
    ThirdParty(QObject* parent=Q_NULLPTR) { 
    // Init A 

    // Connect to B through A 
    connect(this->integrationObj, SIGNAL(signalData(int)), this, SLOT(slotGetData(int))); 
    } 
private slots: 
    // Connect A::signalData(int x) to this slot and do something with the x (change UI, whatever) 
    void slotGetData(int x); 
private: 
    A* integrationObj; 
} 

Класс ThirdParty прирост непрямого доступа к конкретным функции от B до A.

Теперь дилемма я столкнулся заключается в следующем:

  • Должен ли я просто ретранслировать сигнал данных, который поступает из B через A и выставить его в качестве сигнала A или
  • Должен ли я просто вернуться a const ссылка на B, чтобы разрешить класс, в котором есть A (чтобы он мог использовать B) для прямого подключения к B's signalData(int x)?

В первом случае (который я есть) я в основном должны отражать каждый сигнал B хочет, чтобы предложить снаружи внутрь A (путем предоставления соответствующих закрытых слотов в A, а также сигналы, которые являются в основном такими же, как B 's). Излишне говорить, что это приводит к тому, что у него слишком много одинакового материала, а также имеет некоторое (хотя и незначительное) влияние на производительность, так как я получаю 2 сигнала (от B до A, а затем от A до любого другого объекта A) и 2 слота (один из A для получения сигнала от B и один в зависимости от того, какой другой объект имеет A, чтобы получить сигнал от A).

Второй случай кажется хорошим, но я боюсь, что я буду подвергать особенности B которых класс, содержащий A не может быть разрешено иметь доступ к

Если второй случай реализуется, я бы что-то вроде этого (B не изменяется):

class A : public class QObject { 
    Q_OBJECT 
public: 
    A(QObject* parent=Q_NULLPTR); 
    const B* getB() const; // Return a reference to B that cannot be changed but can be used to expose B's slots and signals 
signals: 
private slots: 
private: 
    B* workerObj; 
    QThread worker; 
    QTimer workerTimer; 
} 

class ThirdParty : public class QWidget { 
    Q_OBJECT 
public: 
    ThirdParty(QObject* parent=Q_NULLPTR) { 
    // Init A 

    // Connect to B directly! 
    connect(this->A->getB(), SIGNAL(signalData(int)), this, SLOT(slotGetData(int))); 
    } 
private slots: 
    // Connect B::signalData(int x) to this slot and do something with the x (change UI, whatever) 
    void slotGetData(int x); 
private: 
    A* integrationObj; 
} 

Что мне здесь делать? К сожалению, нет частных сигналов, следовательно, все сигналы B, но и все его публичные слоты будут выставлены. Если все это должно быть использовано, нет проблем с этой степенью воздействия, но в противном случае ... не так много.

ответ

0

facepalm У меня уже было решение в другом проекте.: D Мне просто нужно предоставить connectTo(QObject* thirdparty) внутри A, который внутренне соединяет слот thirdparty только с определенным сигналом B, таким образом не подвергая вещи от B, которые не должны быть выставлены!

Еще одно лучшее решение - использовать соединение сигнал-сигнал (connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type)) или использовать отношение дочерний-родительский, хотя в последнем случае я должен убедиться, что на самом деле установлен родительский элемент. Это также известно как передача сигнала и требует 2 сигналов, но никаких дополнительных слотов. Так как A видна ThirdParty я могу сделать (this здесь представляет ThirdParty) connect(this, SIGNAL(signalFromThirdPartyToB()), this->a, SIGNAL(signalFromAToB())) установить пересылку ThirdParty сигналов B через A, а затем сделать фактическое соединение сигнал-слот между сигналом переадресации в A к слоту в B по телефону (this здесь представляет A) connect(this, SIGNAL(signalFromAToB()), this->b, SLOT(slotB())).

+0

Система сигнальных слотов является одним из средств развязывания классов. Использование его для плотной пары классов, как вы делаете, кажется противоречивым. Вообще говоря, если классы A и B взаимодействуют друг с другом, но могут быть развязаны, отделите их и позвольте своему пользователю составить/связать их по мере необходимости. Разумеется, вы можете иметь вспомогательные функции, которые учитывают общие шаблоны связей между A и B, если вы их повторно используете. В идеале A не должен знать тип B и наоборот, и они должны быть построены изолированно. –

+0

'A' и' B' плотно связаны, за исключением очень ограниченного набора функций. «A» - это единственное, что приносит «B», чтобы жить, и в основном несет ответственность за «ThirdParty», чтобы фактически получить какие-либо данные. Многие из функций 'B' на самом деле не слоты, а просто простые функции, к которым должен обращаться только« A ». – rbaleksandar

Смежные вопросы