Newsgroup: it.comp.lang.c++
Titolo: Un problema di eredita' multipla

Salve a tutti,
ho un problema di eredita' multipla che non so come risolvere.
Riguarda l'uso di Qt, ma la soluzione dovrebbe essere strettamente C+
+.
Rapida descrizione: sto scrivendo una piccola chat che fa uso di certi
modem radio che ho. Ho scritto tutto il codice per interfacciarmi a
questi moduli, e l'ho racchiuso in una classe (modemInterface), che mi
da' dei bei metodi come "sendMessage", "addUser", ecc.
La mia idea era quella di dichiarare poi la mia classe "chat" come:
class Chat : public QMainWindow, public modemInterface
per ereditare l'interfaccia grafica di Qt che mi serve, e tutte le
funzionalita' per accedere al modem.
Questo avrebbe funzionato benissimo, ma non avevo fatto i conti con
l'eredita' multipla (che non volevo, semplicemente non me n'ero
accorto): modemInterface eredita da QObject per poter utilizzare il
sistema signal/slot (che e' il cardine intorno a cui volevo costruire
tutto, dalla GUI alla gestione della seriale), e quindi Chat
eredirebbe da QObject tramite sia QMainWindow che modemInterface.
La cosa non si puo' fare (Qt non lo permette).
Quindi... che fo?
Ho trovato questo articolo:
http://doc.trolltech.com/qq/qq15-academic.html
(ultima sezione, sulla multiple inheritance) che dovrebbe rispondere
alla domanda, ma non sono in grado di capirla :(
Come funziona quel wrapper? Come fanno le funzioni pubbliche di
CustomWidget ad arrivare a ClipboardInterface (diventando public slots
nel frattempo??) ?
Dov'e' che sono davvero implementate quelle funzioni?
Qualsiasi suggerimento e' ben accetto... pensavo di aver finito il mio
codice, e ho scoperto che sono tornato a zero e non ho idea di come
ricominciare :(
Pleg

 Pleg
Ciao,
secondo me potresti risolvere tutto semplicemente evitando
l'ereditarierà multipla a favore del contenimento, cioè, io fare
qualcosa del genere:
class Chat : public QMainWindow
{
[...]
private:
     // Contenimento
    modemInterface m_modemInterface;
};
se vuoi tenere l'ereditarietà multipla potresti anche estrapolare da
modemInterface in un'interfaccia pura:
// Interfaccia di ModemInterface
class IModemInterface
{
public:
    virtual void sendMessage() = 0;
};
...quindi poi avresti:
class Chat : public QMainWindow, virtual public IModemInterface
{
[...]
public:
     virtual void sendMessage() { m_modemInterface.sendMessage(); }
private:
     // Contenimento
    modemInterface m_modemInterface;
};
Anche io ho avuto qualche problema nella gestione di alcune
limitazioni di QT. Molto spesso ho utilizzato questo metodo per
risolvere...
Spero di esserti stato utile.
Ciao
Gian

Ciao,
si' la soluzione dovra' essere qualcosa del genere, ma non capisco
bene come possa funzionare. Un conto sono i metodi "normali" (per i
quali non ci sarebbe nessun problema a fare come dici), ma per slot e
segnali? Funzionano allo stesso modo?
Cioe': se sendMessage() e' un signal, e ad es. receiveMessage() e' uno
slot, posso comunque fare cosi'?
class Chat : public QMainWindow, virtual public IModemInterface
{
[...]
public slots:
     virtual void receiveMessage() { m_modemInterface.receiveMessage
(); }
signals:
     virtual void sendMessage() { m_modemInterface.sendMessage(); }
private:
    modemInterface m_modemInterface;
};
Se si' basta, sono a cavallo :) e' che mi sembra strano (e non capisco
perche' l'articolo che ho postato faccia tutta quella complicazione
coi cast, proprio non ho capito cosa facciano).
Thx,
Pleg


coi cast, proprio non ho capito cosa facciano).
L'articolo di QT è una complicazione a mio avviso inutile. Oltretutto
la soluzione proposta non funziona. Ho fatto qualche test e il
risultato non è quello che l'articolo vuole ottenere ma probabilmente
il codice si riferisce a chissà quale versione precedente di Qt.
Se ti posso dare un consiglio io nella classi non GUI evito di
utilizzare il meccanismo dei segnali a favore di una classica
implementazione del pattern Observer (implementazione che può essere
complessa se hai bisogno che il meccanismo funzioni in un ambiente
multithread).
Questo porta generalmente alcuni vantaggi:
- il meccanismo signal/slot di Qt è tremendamente lento se comparato
con una chiamata a funzione normale (fino a 10 volte più lento)
- ti porti dietro un legame con la libreria che rende complesso il
testing o il riutilizzo.
In ambito strettamente GUI invece i segnali sono ottimi (in questo
ambito i la "lentezza" dei segnali è trascurabile in quanto, in
generale, il repaint di una  finestra è di gran lunga la cosa più
lenta e dispendiosa)
Ciao
Gian

 il codice si riferisce a chissà quale versione precedente di Qt.
Gia', ieri sera avevo provato anch'io, un bell'esempio di copy-paste-
compile-fail-bestemmie :)
Fallisce il cast a qobject perche' vuole che la classe virtuale che
definisce l'interfaccia erediti da QObject (che e' proprio quello che
volevamo evitare...)
Cmq, grazie mille per tutto il resto, stasera metto a posto il
maledetto codice!
Pleg