web-dev-qa-db-ja.com

QObjectの多重継承

C++/Qtのクラスでミックスを使用して、一連のウィジェット全体に共通のインターフェースを提供しようとしています。インターフェースは、他のウィジェットクラスの基本クラスとして定義されている場合、ウィジェット自体がこれらのシグナルを持つように定義されています。

_class SignalInterface: public QObject {
    Q_OBJECT

    public:
    SignalInterface();
    virtual ~SignalInterface();

    signals:
    void iconChanged(QIcon);
    void titleChanged(QString);
}

class Widget1: public SignalInterface, QWidget{

    public:
    Widget1()
    virtual ~Widget1()

    // The Widget Should Inherit the signals
}
_

クラス階層を見ると問題が明らかになり、_Widget1_がQWidgetSignalInterfaceから継承し、どちらもQObjectから継承する、多重継承の恐ろしいひし形に偶然遭遇しました。これにより問題が発生しますか?

この問題は、QObjectクラスが純粋に仮想である場合(そうでない場合)に簡単に解決できることがわかっています。

可能な解決策は次のとおりです。

_class Interface: public QWidget {
Q_OBJECT

signals:
void IconChanged(QIcon);
void titleChanged(QString);
}

class Widget1: public Interface {

}
_

ここでの問題は、QWidgetを継承するコードがすでにたくさんあり、それをハックするのが面倒なことです。別の方法はありますか?

41
Anonymous

残念ながらQObjectを2回継承すると、mocで問題が発生します。

http://qt-project.org から:

多重継承を使用している場合、mocは最初に継承されたクラスがQObjectのサブクラスであると想定します。また、最初に継承されたクラスのみがQObjectであることを確認してください。

デリゲートパターンのようなものを使用するか、IsA関係ではなくHasAで再作成することをお勧めします。

52
szatmary

基本クラスがQObjectからprivatelyを継承する場合、Qtは多重継承を許可します。

例:

class Base: private QObject {
   Q_OBJECT
   /*Can use signals and slots like any other QObject-derived class*/
};

class Derived1: public Base {
   /*Cannot use signals/slots because it does not "see" that Base inherits from QObject*/
};

class Derived2: public QWidget, public Base {
   Q_OBJECT
   /*Can use signals/slots plus has all the functionality of QWidget and Base*/
};

もちろん、私的な継承はまったく別の動物であり、本当に必要な解決策をあなたに与えないかもしれません。私がそれを使用するのは、基本クラスでのみ信号/スロットを使用することを回避できる場合です。派生クラスでQObjectの動作が本当に必要な場合は、そのクラス専用にQObjectから継承します。

7
Carlton