Problema Qt Herencia Multiple

560 views
Skip to first unread message

Gaston

unread,
Dec 7, 2010, 3:42:33 PM12/7/10
to CyC++ Buenos Aires
Gente;
Desarrollando con Qt he descubierto q no soporta herencia multiple (de
2 QObjects), y necesito utilizar herencia multiple a modo de
interfaces (clase abstracta pura) con Slots. Basicamente es;

Clase interface : public QObject{
Q_OBJECT

public slots:
virtual void slot1() = 0;
}

Clase tipoA : public QObject{
Q_OBJECT
}

Clase tipoB: public tipoA, public interface{
Q_OBJECT

public slots:
virtual void slot1();
}

Esto obviamente no funciona, y no se si existe alguna receta para
solucionar este problema.

Ing. Esteban D. Papp

unread,
Dec 7, 2010, 4:12:25 PM12/7/10
to cp...@googlegroups.com
2010/12/7 Gaston <medina...@gmail.com>

Gente;
Desarrollando con Qt he descubierto q no soporta herencia multiple (de
2 QObjects),

Deberia, creo que tu problema esta en que estas poniendo dos veces Q_OBJECT
Esta macro define unos metodos internos, por lo tanto, no podes definirlos dos veces en una derivada.
 
y necesito utilizar herencia multiple a modo de
interfaces (clase abstracta pura) con Slots. Basicamente es;

Clase interface : public QObject{
Q_OBJECT

public slots:
   virtual void slot1() = 0;
}

Clase tipoA : public QObject{
Q_OBJECT
}

Clase tipoB: public tipoA, public interface{
Q_OBJECT

public slots:
   virtual void slot1();
}

Esto obviamente no funciona, y no se si existe alguna receta para
solucionar este problema.

En tu caso, la interfaz no es necesario que implemente Q_OBJECT. 
Hilando mas fino, tampoco deberia ser necesario que herede de QObject, porque QObject no es una interfaz, por lo tanto tu interfaz tampoco lo seria.

Si tenes el error que te tira, mandarlo asi entro mas en detalles.

Salu2
Esteban

Enrique Nieloud

unread,
Dec 7, 2010, 4:12:58 PM12/7/10
to cp...@googlegroups.com
Interesante problema.
La documentación dice claramente que no se puede:

http://doc.qt.nokia.com/4.6/moc.html

Multiple Inheritance Requires QObject to Be First

If you are using multiple inheritance, moc assumes that the first
inherited class is a subclass of QObject.
Also, be sure that only the first inherited class is a QObject.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Si se te ocurre alguna solución no estándar me gustaría saberla.

Hugo Villalba

unread,
Dec 7, 2010, 4:17:18 PM12/7/10
to cp...@googlegroups.com
En Visual Studio tira el siguiente error

1>.\main.cpp(33): Warning: Class tipoB inherits from two QObject
subclasses tipoA and interface. This is not supported!


2010/12/7 Ing. Esteban D. Papp <esteba...@gmail.com>:

> --
> ¿Eres miembro de "CyC++ Buenos Aires" verdad? Si no lo eres, has recibido
> este mesaje por error.
> En caso de duda visita "http://groups.google.com/group/cppba"

Ing. Esteban D. Papp

unread,
Dec 7, 2010, 5:08:23 PM12/7/10
to cp...@googlegroups.com
Ahi le di una vuelta

class interface : public QObject {
Q_OBJECT
public slots:
   virtual void slot1() = 0;
};

class tipoA : public QObject {
};

class tipoB : public tipoA, public interface{

public:
   virtual void slot1();
};


como el slot es traducido por interface, no hace falta que lo sea por tipoB, por eso podes prescindir de Q_OBJECT en tipoB y por lo tanto heredar de ambos.
De todas formas, fijate bien que es lo que queres hacer con slot1, puede que no se este llamando en tipoB, habria que chequear si el codigo generado por el moc soporta este truco. BTW, esto es algo peligroso porque no es recomendado... :)
Fijate si no lo podes solucionar haciendo que tu interfaz no herede de QObject, aun asi podes hacer metodos virtuales, y que los hijos los marquen como slots.

De todas formas, me parece que no estas usando bien el slot en interface, si ya sabes que todos los hijos lo van a implementar, deberias crear un slot y que llame a un metodo virtual que todos los hijos tengan.

salu2
estebanp


2010/12/7 Hugo Villalba <hugo.v...@gmail.com>

Juan Manuel Ollé

unread,
Dec 7, 2010, 6:38:45 PM12/7/10
to cp...@googlegroups.com
A modo de curiosidad, probaste con herencia virtual para que solo existe un QObject?

Ing. Esteban D. Papp

unread,
Dec 7, 2010, 6:42:20 PM12/7/10
to cp...@googlegroups.com
Si probe, pero el problema no es el compilador de C++, ese encuentra ambiguedad en unos metodos que genera qt...

El que esta tirando el error es el compilador moc, viendo el codigo, veo que chequea si es un QObject viendo la macro Q_OBJECT, asi que la herencia multiple de QObject se puede hacer, lo que no se puede hacer es heredar de mas de una clase que tenga la macro Q_OBJECT

salu2
estebanp


2010/12/7 Juan Manuel Ollé <juanman...@gmail.com>

Gaston

unread,
Dec 8, 2010, 11:20:03 AM12/8/10
to CyC++ Buenos Aires
Ok, muchas gracias Esteban, muy buena info. También encontré este
documento navegando y me parece interesante compartirlo,

http://doc.trolltech.com/qq/qq15-academic.html
//En la sección Multiple Inheritance

Igualmente me parece que tu solución plantea un punto de vista que no
había tenido en cuenta!

Saludos

On 7 dic, 20:42, "Ing. Esteban D. Papp" <esteban.p...@gmail.com>
wrote:
> Si probe, pero el problema no es el compilador de C++, ese encuentra
> ambiguedad en unos metodos que genera qt...
>
> El que esta tirando el error es el compilador moc, viendo el codigo, veo que
> chequea si es un QObject viendo la macro Q_OBJECT, asi que la herencia
> multiple de QObject se puede hacer, lo que no se puede hacer es heredar de
> mas de una clase que tenga la macro Q_OBJECT
>
> salu2
> estebanp
>
> 2010/12/7 Juan Manuel Ollé <juanmanuelo...@gmail.com>
>
>
>
>
>
>
>
> > A modo de curiosidad, probaste con herencia virtual para que solo existe un
> > QObject?
>
> > El 7 de diciembre de 2010 19:08, Ing. Esteban D. Papp <
> > esteban.p...@gmail.com> escribió:
>
> >> Ahi le di una vuelta
>
> >> class interface : public QObject {
>
> >> Q_OBJECT
>
> >> public slots:
>
> >>    virtual void slot1() = 0;
>
> >> };
>
> >>  class tipoA : public QObject {
>
> >> };
>
> >>  class tipoB : public tipoA, public interface{
>
> >>  public:
>
> >>    virtual void slot1();
>
> >> };
>
> >> como el slot es traducido por interface, no hace falta que lo sea por
> >> tipoB, por eso podes prescindir de Q_OBJECT en tipoB y por lo tanto heredar
> >> de ambos.
> >> De todas formas, fijate bien que es lo que queres hacer con slot1, puede
> >> que no se este llamando en tipoB, habria que chequear si el codigo generado
> >> por el moc soporta este truco. BTW, esto es algo peligroso porque no es
> >> recomendado... :)
> >> Fijate si no lo podes solucionar haciendo que tu interfaz no herede de
> >> QObject, aun asi podes hacer metodos virtuales, y que los hijos los marquen
> >> como slots.
>
> >> De todas formas, me parece que no estas usando bien el slot en interface,
> >> si ya sabes que todos los hijos lo van a implementar, deberias crear un slot
> >> y que llame a un metodo virtual que todos los hijos tengan.
>
> >> salu2
> >> estebanp
>
> >> 2010/12/7 Hugo Villalba <hugo.villa...@gmail.com>
>
> >> En Visual Studio tira el siguiente error
>
> >>> 1>.\main.cpp(33): Warning: Class tipoB inherits from two QObject
> >>> subclasses tipoA and interface. This is not supported!
>
> >>> 2010/12/7 Ing. Esteban D. Papp <esteban.p...@gmail.com>:
> >>> > 2010/12/7 Gaston <medina.gas...@gmail.com>
Reply all
Reply to author
Forward
0 new messages