Seite 1 von 1

Möglichkeit,Diamantvererbung zu umgehen,um Signal zu nutzen?

Verfasst: 24. Juni 2009 09:23
von Chris81T
Hallo,

folgendes Szenario (vereinfachter Code):

Code: Alles auswählen

class OwnObject

class OwnButton : public OwnObject, public QPushButton
class OwnLineEdit : public OwnObject, public QLineEdit
Es gibt Klassen (hier OwnButton, OwnLineEdit), die von tpyischen grafischen Objektklassen (hier QPushButton, QLineEdit) abgeleitet sind, um diese spezifisch zu erweitern.
Nun ist es so, dass diese Klassen zu ihrer Erweiterung einige Gemeinsamkeiten haben, die in eine abstrakte Oberklasse (hier OwnObject) ausgelagert werden, damit diese nicht in jeder Klasse implementiert werden müssen. Bis hier ist noch kein Problem.

Nun gehen wir mal von aus, es wird ein gemeinsames Signal oder Slot für die "Own-Klassen" benötigt, was dann nach obriger Struktur in die "OwnObject" Klasse implementiert werden müsste:

(vereinfachter Code):

Code: Alles auswählen

class OwnObject
{
...
signals:
    void ownSignal();
};

class OwnButton : public OwnObject, public QPushButton
class OwnLineEdit : public OwnObject, public QLineEdit
Nur müsste ja an dieser Stelle die Klasse "OwnObject" nun auch von QObject abgeleitet werden und das Q_OBJECT Marco verpasst bekommen.

Dann kommst ja zur Diamantvererbung, da ja auch QPushButton, QLineEdit,... auch von QObject abgeleitet sind.
Man könnte sowas nun durch "virtuelles Ableiten" gelöst bekommen, aber es ist immer die Frage, ob das das "Gelbe vom Ei" ist und nicht später für böse Überraschungen sorgt.

Ich weis, dass man zB. mit Q_INVOKABLE FUnktionen den MOCompiler bekannt machen kann, die keine Slots sind (Gebrauch zB bei QScript).

Ein Kollege meint mal gehört zu haben, dass man Signale auch ohne QObject Klassenableitung definieren und nutzen kann. Er ist sich aber nicht sicher.
Im Assistent steht auch was von Q_SIGNAL(S), Q_SLOT(S), die ja für 3rd party signal/slot Mechanismen gedacht sind.

Kennt jemand eine solche Problemstellung und hat jemand einen guten Lösungsvorschlag, Tipp?

Vielen Dank

Verfasst: 24. Juni 2009 13:00
von RHBaum
1.
Nun gehen wir mal von aus, es wird ein gemeinsames Signal oder Slot für die "Own-Klassen" benötigt
eigentlich brauchst du genau das nicht wirklich.
Die signal Slot verwaltung bekommst du ja durch das QObject soweiso scho verpasst. Du kannst also alle QObjects verbinden.

Durch die Basisklasse bekaemst du nur das Signal definiert. Das ist eine Zeile gespaart. Das Signal muss überhaupt ned virtuell sein ... die generalizitaet kriegst du schon durch den Signal,Slot mechanismus. Sich dadurch den Aerger mit Mehrfachvererbung einzuhandeln isses nicht wert.
Also wenn du in jeder deiner Klassen

Code: Alles auswählen

signals:
    void ownSignal(); 
definierst, langt das und erspart dir aerger.

Falls du doch noch virtuelle funktionen hasst, kannst die auf auf den Signal/Slot mechanismus Mappen

Falls du wirklich richtige Ableitung brauchen solltest:

Code: Alles auswählen

class OwnObject public: QObject
...

Code: Alles auswählen

class OwnButton public: OwnObject 
{
private: 
    QPushButton * mpMyControl; 
}
Und alle Benoetigten methoden von QPushbutton OwnButtun neu definieren und an mpMycontrol durchreichen.
Tja, Vererbung ist halt ned da um sich tipparbeit zu erleichtern ...

Ciao ...

Verfasst: 24. Juni 2009 13:14
von pfid
Kann deine Buttonklasse von deiner Object-Klasse und QPushButton erben, wenn beide von QObject kommen?

Verfasst: 24. Juni 2009 13:39
von solarix
Nein.. das was hier diskutiert wird (Erben von zwei QObjecten) ist gar nicht moeglich.. siehe http://doc.trolltech.com/4.5/moc.html

Verfasst: 24. Juni 2009 14:02
von Chris81T
Das Signal muss überhaupt ned virtuell sein ...
Ich geh mal von aus, du beziehst das auf meinen Kommentar
Man könnte sowas nun durch "virtuelles Ableiten" gelöst bekommen,
?!

Wenn ja, habe ich mich etwas undeutlich ausgedrückt. Ich meinte Folgendes (Bsp. aus einem Cpp Buch):

Code: Alles auswählen

class A {...};
class A1 : virtual public A {...};
class A2 : virtual public A {...};
class B : public A1, public A2 {...};
Also virtuelles Ableiten einer Klasse.
Nur sogesehen wäre das nicht umzusetzen, da ja man schlecht in der QWidget Klasse, wovon QPushButton erbt, ein virtual public QObject setzen kann.

Ich versteh dich schon, von wegen, dass dann in jeder Klasse das Signal bekannt gegeben wird. Das hab ich mir auch gedacht und mach das auch aktuell schon. Aber die Konstellation hatte mich einfach mal interessiert. Falls nun jemand eine interessante Lösung dazu gehabt hätte, hätte ich es mir dann überlegen, testen können..

Verfasst: 24. Juni 2009 16:16
von upsala
Ein Kollege meint mal gehört zu haben, dass man Signale auch ohne QObject Klassenableitung definieren und nutzen kann. Er ist sich aber nicht sicher.
Ja, fast. QSignal Aber halt nicht mehr in Qt4.

Verfasst: 24. Juni 2009 17:19
von RHBaum
Ich geh mal von aus, du beziehst das auf meinen Kommentar
Neee eher prinzipiell ^^

In deinem Fall der Zusammenhang zwischen Signal, und die Idee: Vererbung einzusetzen !

Zitat aus nem guten Design C++ Buch (weiss ned mehr welches):
"Vererbe nie zum wiederverwenden, sondern um wiederverwendet zu werden"

Unterstreicht den Sinn und das Wesen von polymorphie. das ist nicht da um code wiederzuverwenden, sondern um Objecte zu erzeugen die sich verhalten wie ein anderes. Schnittstellenprinzip, austauschen von implementationen zur laufzeit.

Und deine Idee wegens dem Signal da vererbung einzusetzen, verstoesst halt gegen das prinzip.
Genau so wie in der Praxis. Kriegst du eine Klassen zum laufen, in dem du ein Teil oder alle Methoden einer anderen klasse einfach nachbildedest, solltest du das auch tun, und nicht von der anderen Klasse ableiten.

Ciao ...

Verfasst: 24. Juni 2009 17:56
von solarix
upsala hat geschrieben:
Ein Kollege meint mal gehört zu haben, dass man Signale auch ohne QObject Klassenableitung definieren und nutzen kann. Er ist sich aber nicht sicher.
Ja, fast. QSignal Aber halt nicht mehr in Qt4.
In Qt4: http://doc.trolltech.com/4.5/qmetaobjec ... vokeMethod