2011-12-20 16 views
34

Estoy tratando de usar mix en clases para C++/Qt para proporcionar un conjunto completo de widgets con una interfaz común. La interfaz se define de tal manera que si se define como la clase base para otras clases de widgets, entonces el widget tendrá esas señales. es decir, consulte a continuación.QObject Multiple Herencia

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 cuanto a la jerarquía de clases el problema se hace evidente, he tropezado con el diamante temida en herencia múltiple, donde el Widget1 hereda de QWidget y SignalInterface, y tanto, que heredar de QObject. ¿Esto causará algún problema?

Sabemos que este problema se puede resolver fácilmente si la clase QObject es puramente virtual (lo cual no es el caso).

Una posible solución sería

class Interface: public QWidget { 
Q_OBJECT 

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

class Widget1: public Interface { 

} 

El problema aquí es que ya tengo gran cantidad de código que heredan de QWidget, y su dolorosa para introducirse en el que. ¿Hay alguna otra manera?

+0

Eche un vistazo a: http://stackoverflow.com/questions/17943496/declare-abstract-signal-in-interface-class/17943699#17943699 –

Respuesta

42

Desafortunadamente heredar QObject dos veces causará problemas en moc.

De http://qt-project.org:

Si está utilizando herencia múltiple, moc asume que el primer clase heredada es una subclase de QObject. Además, asegúrese de que solo la primera clase heredada sea un QObject.

Sugeriría usar algo más como el patrón delegado, o recrear con una relación HasA no una relación IsA.

5

Qt permite la herencia múltiple si la clase base hereda en privado de QObject.

Ejemplo:

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

Por supuesto, la herencia privada es un animal completamente diferente y no le puede dar la solución que realmente necesita. Lo que uso es cuando puedo salirse con la suya usando señales/ranuras solo en la clase base. Cuando realmente necesito el comportamiento QObject en una clase derivada, heredo de QObject específicamente para esa clase.

+0

Usando Qt5.9, esta solución comete un error al compilar el moc archivos generados: 'static_cast': conversiones ambiguas de 'QObject *' a 'myClass *' –