【发布时间】:2013-02-03 17:54:44
【问题描述】:
使用 Qt 5.0.0
以下大致是一个Observer 模式(代码被剥离到最低限度,仅用于解释问题):
class A : public QObject
{
Q_OBJECT
public:
void registerListner(Observer *pObs);
static A* getInstance();
signals:
void sig();
};
void A::registerListner(Observer *pObs)
{
connect(this, SIGNAL(sig()), pObs, SLOT(slo));
}
////////////////////////////////////////////////////////////////
class Observer : public QObject
{
Q_OBJECT
public slots:
virtual void slo() = 0;
};
class ConcreteObserver : public Observer , public QWidget
{
Q_OBJECT
public: //re-mentioning "slots" is not necessary
virtual void slo();
};
ConcreteObserver *pCObs = new ConcreteObserver;
A::getInstance()->registerListner(pCObs);
/////////////////////////////////////////////////////////////
问题(除了可怕的钻石): 不能从 QObject 继承多次 - moc 不允许。 一种可能的解决方案是从 QWidget 派生 Observer,然后仅从 Observer 派生 ConcreteObserver。然而,这对 ConcreteObserver 施加了限制。也许 ConcreteObserver_2 需要从 QDialog 派生等等。
我该如何解决这个设计问题? Qt 5.0.0 Signal-Slot 有什么特定的东西(除了早期版本)可以解决这个问题,或者你有什么建议?
【问题讨论】:
-
你为什么需要那个 Observer 类?
-
观察者模式 :) 那是选定的设计。在这里可能看起来并不明显,但如果一个人经历了整个项目需求,就会有意义。这只是显示问题所在的最低限度
-
在上面的示例中,您不需要它。您可以将
QObject*传递给A的registerListener。 -
@Mat 但
QObject不包含用户定义的插槽slo。它将如何工作?此外,我想通过设计设置一个约束,即所有注册的类都应该重新实现插槽slo。或者也许我没有完全理解你 - 在这种情况下进一步解释自己 -
如果您将参数更改为
QObject*,您的代码将正常编译,但如果该特定 QObject 未实现该插槽,您将在运行时收到警告。 (程序不会失败,只是不会连接任何东西。)如果需要,您也可以进行运行时检查。
标签: c++ qt observer-pattern qt5