web-dev-qa-db-fra.com

Héritage multiple QObject

J'essaie d'utiliser mix dans les classes pour C++/Qt pour fournir tout un tas de widgets avec une interface commune. L'interface est définie de manière telle que si elle est définie comme la classe de base pour d'autres classes de widgets, alors le widget lui-même aura ces signaux:

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
}

En regardant la hiérarchie des classes, le problème devient apparent, je suis tombé sur le diamant redouté dans l'héritage multiple, où le Widget1 hérite de QWidget et SignalInterface, et les deux héritent de QObject. Cela causera-t-il des problèmes?

Nous savons que ce problème peut être facilement résolu si la classe QObject est purement virtuelle (ce qui n'est pas le cas).

Une solution possible serait:

class Interface: public QWidget {
Q_OBJECT

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

class Widget1: public Interface {

}

Le problème ici est que j'ai déjà beaucoup de code qui hérite de QWidget, et c'est pénible de le pirater. Y a-t-il une autre façon?

41
Anonymous

Malheureusement, hériter deux fois de QObject causera des problèmes dans moc.

De http://qt-project.org :

Si vous utilisez l'héritage multiple, moc suppose que la première classe héritée est une sous-classe de QObject . Assurez-vous également que seule la première classe héritée est un QObject .

Je suggérerais d'utiliser quelque chose de plus comme le modèle de délégué, ou de recréer avec une relation HasA et non IsA.

52
szatmary

Qt permet l'héritage multiple si la classe de base hérite en privé de QObject.

Exemple:

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*/
};

Bien sûr, l'héritage privé est un tout autre animal et peut ne pas vous donner la solution dont vous avez vraiment besoin. Ce que je l'utilise, c'est quand je peux m'en sortir avec l'utilisation de signaux/slots uniquement dans la classe de base. Lorsque j'ai vraiment besoin d'un comportement QObject dans une classe dérivée, j'hérite de QObject spécifiquement pour cette classe.

7
Carlton