Newsgroup: it.comp.lang.c++
Titolo: [c++] grossi problemi con puntantori a liste di puntatori ....

Ciao a tutti
C'è qualcuno di voi che mi sa spiegare perchè questo semplice codice
non funge?
Mi sembra che il cast di una lista di puntatori mi crei problemi...
grazie anticipatente!
#include<list>
#include<iostream>
using namespace std;
class Interface1
{
        public :
                virtual int getValue1() = 0;
};
class Interface2
{
        public :
                virtual int getValue2() = 0;
};
class Concrete : public Interface2, public Interface1
{
        public :
                Concrete() {v1 = 111; v2 = 555;}
                int getValue1() {return v1;};
                int getValue2() {return v2;};
        private :
                int v1;
                int v2;
};
void stampa(Interface1* i);
void stampa(list<Concrete*>* lstptrConcrete);
void stampa(list<Interface1*>* lstptrConcrete);
int main()
{
        Concrete *c = new Concrete;
        stampa((Interface1*)c);   // OK : ovviamente stampa giusto
        list<Interface1*>* lstptrInterface1;
        list<Concrete*>* lstptrConcrete = new list<Concrete*>;
        lstptrConcrete->push_front(c);
        stampa(lstptrConcrete); // OK : ovviamente stampa giusto
        lstptrInterface1 = (list<Interface1*>*)lstptrConcrete;
        //lstptrInterface1 =
reinterpret_cast<list<Interface1*>*>(lstptrConcrete);
 
        stampa(lstptrInterface1); // NOOO : STAMPA SBAGLIATO!!
        return 0;
}
void stampa(Interface1* i)
{
        cout << i->getValue1();
}
void stampa(list<Concrete*>* lstptrConcrete)
{
    if (!lstptrConcrete->empty()) {
        list<Concrete*>::iterator it = lstptrConcrete->begin();
        for ( ; it != lstptrConcrete->end(); ++it ) {
                cout << endl;
                cout << "Valore1 : " << (*it)->getValue1();
                cout << ", ";
                cout << "Valore2 : " << (*it)->getValue2();
                }
    }
}
void stampa(list<Interface1*>* lstptrConcrete)
{
    if (!lstptrConcrete->empty()) {
        list<Interface1*>::iterator it = lstptrConcrete->begin();
        for ( ; it != lstptrConcrete->end(); ++it ) {
                cout << endl;
                cout << "Valore1 : " << (*it)->getValue1();
                }
    }
}

 
'list<Interface1*>' e 'list<Concrete*>' sono tipi distinti non 
imparentati. Non è legittimo usare un puntatore alla seconda come fosse un 
puntatore alla prima. Non a caso hai dovuto usare 'reinterpret_cast'.
Max


in che senso non sono imparentati? il fatto che Concrete estenda Interface1
non è sufficiente ? (evidentmente no)
Inoltre anche se uso  reinterpret_cast non mi funziona lo stesso. Sono
evidenti lei mie grosse lacune in materia....
Io ho assulatamente bisogno di lavorare tramite delle liste di
puntantori.Che tipo di soluzione posso adottare se la mia risulta
strutturalmente errata?
grazie cmq per l'aiuto.



mi sa che il messaggio che ho mandato di riposta non è arrivato...
Non capisco bene come mai non dovrebbe funzionare...non posso utilizzare
delle liste di puntatori e sfruttare il polimorfismo?
Inoltre il 'reinterpret_cast non mi risolve il mio problema.
tnx a lot!

 grazie cmq per l'aiuto.
Messa cosi', sembrerebbe proprio che la gerarchia di classi richieda un 
po' una revisione. Ma con un esempio cosi' astratto, e' difficile dire 
come risolvere il tuo problema. Per lo meno, a me non vengono in mente 
altre risposte, cosi' su due piedi :P
-- 
Mat/tia Belletti             - Graduate student @ 
cs.unibo.it
ICQ: 33292311                - email: 
mbel...@cs.unibo.it
IRC: RedGlow                 - site(s): 
http://mbellett.web.cs.unibo.it/
Red...@jabber.linux.it/Gaim
 - Linux user 299762 @ machine 213003

 strutturalmente errata?
Non saprei. Non sono chiare le tue esigenze. Forse è sufficiente 
templatizzare le funzioni che devono operare sui due tipi di list<>.
Max

 delle liste di puntatori e sfruttare il polimorfismo?
No. 
semmai ti potrebbe servire una costruzione del tipo:
template<typename T>
class C{
    template<typename U>
    void f(const U&);
}
E' chiaro cosa succede in questo caso?
Io non ho guardato il tuo codice (pigrizia mia) ma imho in questo modo
potrebbe venirti qualche illuminazione (btw, da quanto ho letto un
consiglio simile te lo ha dato pure Max.)
-- 
[ RiK0                                ]
[ non credo negli schemi non vincenti ]
[ two is an odd prime number          ]

Max
Comincio a capire quello che dici :((
Quella dei template potrebbe essere una buona soluzione. Purtroppo non sono
molto pratico del loro uso. Oltre al fatto che sto cercando di scrivere un
codice abbasta semplice da  farlo riusare a persone non "espertissime"
(evidentemente come me hehe)
Non voglio annoiarvi dell'altro..per cui vi direttamente quali erano le mie
intensioni iniziali
SUpponiamo di avere
class ConcreteA : public Interface1, public Interface2 {...};
supponiamo di volere mplementare una funzione che faccia un sort in
funzione  del parametro v1 (getValue1()).
Per cui avrei un prototipo del tipo 
void sort_by_v1(list<ConcreteA*>* lst)
ovviamente questa funzione opera solo su liste di tipo list<ConcreteA*>*.
Per cui se in futuro avessi bisogno di un 
class ConcreteB : public Interface1 {...};
mi toccherebbe rifare il sort specifico.
Mi sembrava più utile invece creare un 
void sort_by_v1(list<Interface1*>* lst)
che a precindere da chi concretamente realizza questa implementazione 
potesse svolgere il suo compito, in virtù del fatto che l'unico metodo 
utilizzato è getValue1()
Spero di essermi spiegato ... purtoppo spesso nn ci riesco :P
grazie per tutto le indicazioni sin qui fornitemi!

Comincio a capire quello che dici :((
Ho fatto un po' di prove con i template, come da consiglio. La cosa
funziona piuttosto bene ... anche se č "brutta" a vedersi . Sarebbe piů
bello se per magia funzionasse il cast come avevo erroneamente provato io
hehehe :P
grazie davvero a tutti per il prezioso aiuto che mi avete dato!