由于访问deleteLater()方法,QObject的多重继承

时间:2013-12-11 12:25:38

标签: qt inheritance qobject

我在程序中使用observer-observable模式。在我不得不稍微更改代码之前,一切正常。如果确切的话,我改变了IObserver类的继承 - 现在它继承了QObject:

class IObserver : public QObject
{
...

我之所以这样做是因为只有一件事 - 我需要在观察者中使用deleteLater()方法,因此我可以调用IObserver的虚函数deinitialization()的实现。因此,我可以标准化每个IObserver消息处理程序。

问题是,我已经在某些Observer类中继承了QObject(间接)。像MainForm或AboutDialog。一切都很顺利,直到我尝试在AboutDialog类中调用“connect”方法。

我该怎么办?我真的需要这个deleteLater()方法,因为我不能在IObserver代码中使用“删除这个” - 这将调用IObserver析构函数,而不是例如MainForm或Storage类。

谢谢。

2 个答案:

答案 0 :(得分:1)

  

我真的需要这个deleteLater()方法,因为我不能在IObserver代码中使用“delete this” - 这将调用IObserver析构函数,而不是例如MainForm或Storage类。

如果你让你的析构函数是虚拟的(你应该!)它会很好地调用派生的析构函数。但问题是在处理某些信号/插槽时破坏对象可能会导致事件循环出现问题。无论如何,你必须非常小心delete this

  

问题是,我已经在某些Observer类中继承了QObject(间接)。

你可以实现这一点的一种方法,不确定是否有最好的想法:

template <typename Derived>
class IObserver
{

    // Just to be sure: (C++11)
    static_assert(is_base_of<Derived, QObject>::value,
                  "must inherit from QObject when using IObserver");

    void deleteMe()
    {
        QObject* thisObject = dynamic_cast<QObject*>(this);
        // no need for check if thisObject equals null. static assert does this.
        thisObject->deleteLater();
    }

};

class MainForm : public IObserver<MainForm>, public QMainWindow
{
    // ...
};

我相信这种模式称为静态多态。

答案 1 :(得分:0)

放弃IObserver的QObject继承。而不是将这种方法添加到接口。

class IObserver : public QObject {
public:
   QObject *object() const = 0;
...

然后,如果接口的实现继承QObject,您将从this方法返回object()指针。如果接口的实现没有继承QObject,你可以简单地返回指向一个简单的QObject的指针,它将处理这个对象的破坏。 然后,您只需将deleteLater连接到此方法返回的对象。

非主题
在Qt中使用接口进行观察通常是过时的,插槽和信号完美地完成了这项工作,这是更灵活的方法。