Newsgroup: it.comp.lang.c++
Titolo: Errore con le liste: impazzisco

Ciao a tutti,
sto impazzendo nel riuscire a trovare l'errore in questa
implementazionbe di una lista:
Mi vengono stampati soltanto il primo e l'ultimo valore che inserisco.
Why ?
Grazie a chi mi darà una mano.
Questo è il codice:
#include <iostream.h>
#include <stdlib.h>
class List
{
        public :
                int data;
                void push(List *);
                void init(List *);
                int pop(void);
                List *next;
        private:
                List *head;
};
        void List::init(List *z)
                        {
                                head=z;
                        }
        void List::push(List *t)
                        {
                                int n;
                                List *i;
                                i=new List();
                                cout<<"Dammi un numero :"<<endl;
                                cin>>n;
                                i->data=n;
                                i->next=NULL;
                                t->next=i;
                                t=t->next;
                                delete i;
                        }
        int List ::pop(void)
                        {
                                List *pt;
                                pt=head;
                                head=head->next;
                                int dat=pt->data;
                                delete pt;
                                return dat;
                        }
int main()
{
        int n;
        List r;
        List *a=new List();
        cout<<"Dammi un numero :"<<endl;
        cin>>n;
        a->data=n;
        a->next=NULL;
        r.init(a);
        r.push(a);
        r.push(a);
        int p=r.pop();
        int b=r.pop();
        cout<<p<<endl;
        cout<<b<<endl;
}
--

 Grazie a chi mi darà una mano.
[ codice eliminato per questioni di spazio ]
Ciao,
vedo che hai ancora qualche grosso problema nella programmazione,
ma non ti scoraggiare, quando si inizia e' normale.
Il C++ provvede una classe template lista gia pronta (std::list),
ma e' chiaro che il tuo programma e' soltanto un esercizio per imparare
il linguaggio, quindi, in questo caso, e' giusto provare a implementarsi
da soli classi di questo genere (per poi usare comunque quelle standard
nei programmi "veri").
Per inciso, da come usi la tua classe, piu' che di una lista si 
tratterebbe di una pila (o stack).
Innanzitutto, potresti definire costruttori e distruttori (e sostituire
ad esempio il metodo init con il costruttore di copia).
Dovresti inoltre evitare l'abuso dei puntatori. (Ad esempio, non c'e'
motivo,
in main(), di allocare a con new quando sarebbe piu' indicato usare una
variabile
automatica, come nel caso di r). 
Devi inoltre stare attento a come li usi, nel tuo codice ci sono alcuni
puntatori che
non vengono mai distrutti, e altri che vengono usati anche dopo essere
distrutti.
Non e' chiaro perche' il metodo push prenda come argomento un puntatore
a lista, e
poi ne crei un'altra al suo interno, chiedendone addirittura il valore
all'utente.
Quello che prova a fare, alla fine, e' collegare la lista creata
internamente a
quella passata come argomento (anche qui ci sono  problemi, viene fatta
una delete su un puntatore ancora in uso) lasciando immutata la lista
originale.
Perche la push prende una lista e la pop torna un intero ? C'e' una
certa asimmetria
in questa scelta.
Per prima cosa devi quindi rivedere l'interfaccia della tua classe:
devi decidere che tipo di servizi la tua classe deve fornire agli
utilizzatori
e quali dettagli e' meglio nascondere (ad esempio non c'e' motivo che le
variabili
data e next siano pubbliche).
Prova a considerare, anche, l'ipotesi di semplificare il problema
dividendolo tra
piu' classi, (ad esempio il nodo e la lista o pila). Definisci le
responsabilita 
le classi e il modo in cui dovranno collaborare. 
(per esempio potresti ri-usare una classe nodo in classi diverse per
realizzare 
una lista,  una pila, una coda ecc..)
Prova anche a farti qualche schemino so cosa dovranno fare i vari metodi
(e come 
dovranno farlo) e, quando avrai le idee un po' piu' chiare, riscrivi il
programma.
Buon divertimento,
Fabio

OK tante grazie qualcosa è sicuramente più chiaro.
Ho ripensato l'interfaccia della classe, e ho riprogettato il tutto, ma c'è
ancora qualcosa che non va e non riseco a capire dove.
In particolare la testa dello stack, che io ho memorizzato in un attributo
static, come faccio ad assegnarla solo la prima volta.
Grazie a chi mi aiuta.
Questo è il prototipo:
#include <stdlib.h>
class Stack
{
        public :
                void push(int);
                int pop();
                Stack (int);
                Stack ();
                static Stack *head;
        private:
                int dato;
                Stack *stackElement;
                Stack *next;
};
E questa è l'implementazione:
Stack* Stack::head = NULL;
Stack::Stack(int newElement)
{
        dato = newElement;
        next = NULL;
        stackElement = this;
}
Stack::Stack()
{
}
void
Stack::push(int newElement)
{
        stackElement->dato = newElement;
        if (head->next == NULL)
        {
                cout << "Head->next is NULL"<<endl;
                stackElement->next = NULL;
                head = stackElement;
        }
        else stackElement->next = new Stack(newElement);
}
int
Stack::pop()
{
        int value = head->dato;
        head = head->next;
        return value;


 Grazie a chi mi aiuta.
Ti rispondo in fretta perche' non ho molto tempo a disposizione.
Il suggerimento che ti posso dare e' di separare contenuto e 
contenitore in due classi diverse (magari annidate).
La classe contenitore (stack) potrebbe fornire i metodi push e pop e 
avere il puntatore alla testa, mentre la classe contenuto (il dato)
potrebbe contenere il valore e il puntatore al dato successivo.
Questo semplificherebbe le cose ed eviterebbe lo static.
Tra parentesi l'uso della variabile static ti impedisce di gestire
piu' stack contemporaneamente.
SCA
Fabio