2011-03-23 16 views
6

Tengo un problema con QT con respecto a la herencia múltiple debido a QObject. Sé que muchos otros tienen los mismos problemas, pero no sé cómo debo solucionarlos.Qt herencia múltiple y señales

class NavigatableItem : public QObject 
{ 
    Q_OBJECT 

    signals: 
     void deselected(); 
     void selected(); 
     void activated(); 
}; 

class Button : public NavigatableItem, public QToolButton 
{ 
    Q_OBJECT 

    ... 
} 

class MainMenuOption : public Button 
{ 
    Q_OBJECT 

    ... 
} 

Cuando hago esto

MainMenuOption* messages = new MainMenuOption(); 
connect(messages, SIGNAL(selected()), SLOT(onMenuOptionSelected())) 

que obtendrá el error:

QObject' is an ambiguous base of 'MainMenuOption'

La razón por la que dejo NavigatableItem enherit de QObject debido a las señales. ¿Hay alguna forma de hacer esto?

Editar:

Adición virtual para cada declaración de sucesiones, todavía me da el mismo error:

class NavigatableItem : public virtual QObject 

class Button : public virtual NavigatableItem, public virtual QToolButton 

class MainMenuOption : public virtual Button 

Incluso después de una 'limpia todo', 'qmake correr' y 'construir todos' .

+5

Usted no puede heredar de múltiples QObject subclases. Solo uno de ellos puede ser un QObject, y debe ser el primero en la lista. –

+1

Intente eliminar esos archivos 'moc_ *', '* .obj' y tener una Rebuild All .. – liaK

+0

Ver la pregunta actualizada. La reconstrucción no lo solucionó. – RvdK

Respuesta

8

Se requiere un poco más de código, pero lo que he hecho en el pasado es que uno de ellos (el NavigatableItem en este caso) una pura clase virtual, es decir, interfaz. En lugar de utilizar la macro "señales", conviértalas en funciones protegidas virtuales puras. Luego, multiplique y herede de la clase derivada de QObject, así como de la interfaz, e implemente los métodos.

Sé que es un tanto controvertido, pero evitar la herencia de múltiples implementaciones a toda costa resuelve una serie de problemas y confusión. El Google C++ Style Guidelines lo recomienda, y creo que es un buen consejo.

class NavigatableItemInterface 
{ 
    // Don't forget the virtual destructor! 
    protected: 
     virtual void deselected() = 0; 
     virtual void selected() = 0; 
     virtual void activated() = 0; 
}; 

class Button : public NavigatableItemInterface, public QToolButton 
{ 
    Q_OBJECT 
    ... 
    signals: 
     virtual void deselected(); 
     ... 
} 
+0

Gracias Dave, esto es lo que hice mientras tanto para poder construir el proyecto al menos. Sin embargo, un efecto secundario es que si tengo un objeto textentry que necesita ser un elemento Navigatable, tengo que redefinir cada señal deseleccionada/seleccionada y activada. – RvdK

+2

Tendrá que redefinirlos, pero no debería tener que volver a implementarlos. Normalmente hay una manera de ponerlos en una clase común (tal vez solo una clase de utilidad), incluir esto como un miembro privado de la clase que hereda y hacer que su clase heredada tenga una relación 'has-a' en vez de una 'es -una relación. Sí, es un poco de código adicional, pero la lógica comercial real generalmente se puede mantener en un lugar para evitar errores de "copiar y pegar". He descubierto que vale la pena evitar los otros problemas con la herencia múltiple, pero lo reconozco como una simple opinión. –

1

Usa herencia virtual, p. Ej.

class X : public virtual Y 
{ 
}; 

class Z : public virtual Y 
{ 
}; 

class A : public virtual X, public virtual Z 
{ 
}; 

sólo tendrá una copia de la clase base Y

+0

Agregué virtual a todas las declaraciones de herencia, pero igual me dio el mismo error. – RvdK

+1

Intente regenerar los archivos MOC ejecutando: make distclean; qmake; hacer. – Tobias

+0

Ver la pregunta actualizada. Agregar virtual y reconstrucción no lo solucionó. – RvdK