公开类的内部组件,以防止编写过多代码和影响性能

Exposing internal component of a class in order to prevent writing too much code and impact on performance

本文关键字:代码 性能 影响 内部 组件      更新时间:2023-10-16

假设我有一个类

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并将workerTimertimeout()信号连接到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通过A间接访问B的特定功能。

现在我面临的困境如下:

  • 我应该只是中继来自BA的数据信号并将其公开为A信号还是
  • 我是否应该只返回对Bconst引用以允许其中具有A的类(以便它可以使用B)直接连接到BsignalData(int x)

在第一种情况下(我有),我基本上必须镜像B想要提供给外部内部A的每个信号(通过在A中提供各自的专用插槽以及与B基本相同的信号)。不用说,这会导致有太多相同的东西,并且还会产生一些(即使只是轻微的)性能影响,因为我得到了 2 个信号发射(从BA,然后从A到任何其他对象都有A)和 2 个时隙调用(一个在A中从B获取信号,一个在任何其他对象中A从CC_获取信号(第32页)。

第二种情况看起来不错,但我担心我会暴露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信号以及其所有公共插槽都将暴露。如果要使用所有这些,那么这种程度的暴露没有问题,但除此之外......没那么多。

脸掌我已经在我的另一个项目中有了解决方案。 :D我只需要在A内部提供一个connectTo(QObject* thirdparty),它在内部仅将thirdparty插槽连接到特定的B信号,从而不会暴露B中不打算暴露的东西!

另一个更好的解决方案是使用信令到信号连接(connect(const QObject *sender, const char *signal, const char *method, Qt::ConnectionType type))或使用子父关系,尽管在后者中,我必须确保父级实际设置。这也称为信号转发,需要 2 个信号,但没有额外的插槽。由于AThirdParty可见,我可以做(这里this代表ThirdParty)connect(this, SIGNAL(signalFromThirdPartyToB()), this->a, SIGNAL(signalFromAToB()))设置ThirdParty信号的转发,通过AB,然后通过调用(这里this表示A)connect(this, SIGNAL(signalFromAToB()), this->b, SLOT(slotB())),在A转发信号到B中的插槽之间进行实际的信号槽连接。