Oppure

Loading
03/01/11 14:14
mannhe
Salve a tutti e buon anno..
Come da titolo, sto cercando di realizzare una struttura dati (Lista) utilizzando template e ereditarietà...
In particolare sto cercando di realizzare una lista con cursore unidirezionale.
Ho la classe astratta definita con Template sia per la lista che per ogni elemento della lista.
Nella classe figlia del nodo della lista ho inserito il puntatore al successivo.
nella classe figlia della lista, implemento la lista stessa mediante un vettore di nodi (etichetta+posizione successiva), la posizione successiva contenuta nel nodo indica l'indice dell'elemento del vettore che contiene l'elemento successivo, l'ultimo elemento ha come puntatore al successivo = -1;

Il problema che mi sta facendo impazzire è l'inserimento degli elementi nella lista, dopo aver creato la lista (forzo la creazione con 10 elementi) chiamo il metodo setLista() che è un metodo contenuto nella classe astratta.
setLista() richiama insLista() che è un metodo della classe figlia, in questo passaggio tutto quello che era stato instanziato prima sparisce e non trovando ciò che serve il programma va in errore....

posto il codice di tutto, sperando di essere stato il più chiaro possibile...
grazie anticipatamente

file CellaLista.h
#ifndef CELLALISTA_H
#define CELLALISTA_H
#include <stdlib.h>

using namespace std;

template <class T>
class CellaLista{
      public:
             
             typedef T tipoelem;
             
             CellaLista();
             CellaLista(tipoelem );
             ~CellaLista();
             virtual void scriviCella(tipoelem);
             virtual tipoelem leggiCella() const;
             virtual bool operator==(CellaLista );
     protected:
             tipoelem etichetta;
};
      

template<class T>
CellaLista<T>::CellaLista() {};

template<class T>
CellaLista<T>::CellaLista(tipoelem label){
     etichetta = label;
};

template<class T>
CellaLista<T>:: ~CellaLista(){};

template<class T>
void CellaLista<T>::scriviCella (tipoelem label){
     typename CellaLista<T>::tipoelem etichetta;
     etichetta = label;
};

template<class T>typename
CellaLista<T>::tipoelem CellaLista<T>::leggiCella() const{
      return (etichetta);
};

template<class T>
bool CellaLista<T>::operator==(CellaLista cella){
     return(leggiCella() == cella.leggiCella());
};

#endif



file CellaListaCur.h
#ifndef CELLALISTACUR_H
#define CELLALISTACUR_H
#include <stdlib.h>
#include <iostream>
#include "CellaLista.h"
#define ERR -1

using namespace std;

template <class T>
class CellaListaCur : public CellaLista<T>{
      public:
             typedef typename CellaLista<T>::tipoelem tipoelem;
             typedef int posizione;
           
             CellaListaCur();
             CellaListaCur(tipoelem);
             CellaListaCur(tipoelem, posizione);
             ~CellaListaCur();
			 void scriviCella(tipoelem, posizione);
             posizione getSuccessivo();
             void setSuccessivo(posizione);
      private:
             posizione successivo; 
};
      
template<class T>
CellaListaCur<T>::CellaListaCur(): CellaLista<T>::CellaLista(){
                                   successivo = ERR;
};

template<class T>
CellaListaCur<T>::CellaListaCur(tipoelem label): CellaLista<T>::CellaLista(label){
                                   successivo = ERR;
};

template<class T>
CellaListaCur<T>::CellaListaCur(tipoelem label,posizione p): CellaLista<T>::CellaLista(label){
     successivo = p;
};

template<class T>
CellaListaCur<T>:: ~CellaListaCur()
{};

template<class T>
void CellaListaCur<T>::scriviCella(tipoelem label,posizione p) {
     CellaLista<T>::scriviCella(label);
     successivo=p;
};

template<class T>           
void CellaListaCur<T>::setSuccessivo(posizione p){
     successivo=p;
     };

template<class T>typename
CellaListaCur<T>::posizione CellaListaCur<T>::getSuccessivo(){
          return successivo; 
           };

#endif


file ListaLineare.h
#ifndef LISTALINEARE_H
#define LISTALINEARE_H
#include <iostream>

using namespace std;

template<class T,class P>
class ListaLineare {
      public:
             typedef T tipoelem;
             typedef P posizione;

             // operatori
             virtual void creaLista() =0;
             virtual bool listaVuota() const=0;
             virtual tipoelem leggiLista(posizione) const=0;
             virtual void scriviLista(tipoelem, posizione)=0;
             virtual posizione primoLista() const=0;
             virtual posizione ultimoLista() const=0;
             virtual bool fineLista(posizione) const=0;
             virtual posizione succLista(posizione) const=0;
             virtual posizione predLista(posizione) const=0;
             virtual void insLista(tipoelem, posizione)=0;
             virtual void cancLista(posizione)=0;

             virtual void printLista();
             virtual void setLista();
};

template<class T,class P>
void ListaLineare<T,P>:: printLista(){

      typename ListaLineare<T,P>::posizione p;
      p=primoLista();
      cout<<"\n\n ";
      while(!fineLista(p)){
            cout<<"["<<leggiLista(p)<<"]->";
            p=succLista(p);
      }
      cout<<"[NULL]";
}

template<class T,class P>
void ListaLineare<T,P>:: setLista(){
      typename ListaLineare<T,P>::tipoelem val;
      int num;

      cout<<"\n Con quanti elementi vuoi inizializzare la lista? (max 10)";
      cin>>num;
      while(num<=0){
            cout<<"\n Il numero degli elementi deve essere maggiore"
                <<" o uguale a 1.\n Inserire nuovamente il numero: ";
            cin>>num;
      }
      cout<<" \n Inserisci ora il valore che vuoi assegnare a ciascun elemento:\n\n";
      for(int i=1;i<=num;i++){
            cin>>val;
			cout<<"\n in setLista - primoLista(): "<<primoLista()<<" \n\n";
            insLista(val,primoLista());
      }
}

#endif


file ListaCur.h
#ifndef LISTACUR_H
#define LISTACUR_H
#include <stdlib.h>
#include <iostream>
#include "CellaListaCur.h"
#include "ListaLineare.h"
#define ERR -1

using namespace std;

template<class T>
class Lista : public ListaLineare<T,int>{
      public:
             typedef typename ListaLineare<T,int>:: tipoelem tipoelem;
             typedef typename ListaLineare<T,int>:: posizione posizione;             
             

             Lista();
             Lista(int);
             Lista(const Lista<T>& );
             ~Lista();
             
             // operatori
             void creaLista();
             bool listaVuota() const;
             tipoelem leggiLista(posizione ) const;
             void scriviLista(tipoelem , posizione );
             posizione primoLista() const;
			 posizione ultimoLista() const;
             bool fineLista(posizione ) const;
             posizione succLista(posizione ) const;
             posizione predLista(posizione ) const;
             void insLista(tipoelem, posizione );
             void cancLista(posizione );
             //sovraccarico di operatori
             Lista<T>& operator=(const Lista<T>&); 
             bool operator==(const Lista<T> &) const;
      
   private:
            void cambiaDimensione();
            CellaListaCur<tipoelem> * elementi;
			posizione primo;
            posizione primoVuoto;			
			int dimensione; // dimensione del vettore che realizza la lista
            int lunghezza; // lunghezza effettiva della lista            
};

template <class T>
Lista<T>::Lista(){ 
   Lista(10);
}
   
template <class T>
Lista<T>::Lista(int dim){
	
	dimensione = dim;
    primo = 0;
	cout<<"\n COSTRUTTORE: dim: "<<dim<<" - dimensione: "<<dimensione<<" - primo: "<<primo<<"\n\n"<<endl;
    elementi = new CellaListaCur<tipoelem>[dimensione];
    if (elementi != NULL) {
		cout<<"\n elementi allocato \n\n"<<endl;
		int i;
        for ( i=0; i<dimensione-1; i++) {
            elementi[i].scriviCella(ERR,i+1);
			cout<<i<<". ";
        }
        elementi[dimensione].scriviCella(ERR,ERR);
		cout<<i<<". ";
    }
	else cout<<"\n elementi NON allocato \n\n"<<endl;
    creaLista();
}
   
template< class T >
Lista< T >::Lista(const Lista<T>& lista) {
    dimensione = lista.dimensione;
    lunghezza = lista.lunghezza;
    primo=lista.primo;
    elementi = new CellaListaCur<T> [dimensione];
    if (elementi != NULL) {
        for (int i=0; i<dimensione; i++) {
            elementi[i] = lista.elementi[i];
        }
    }
 
}

template <class T>
Lista<T>::~Lista(){
   // delete [] elementi ;
}

template <class T>
void Lista<T>::creaLista(){
    lunghezza = 0;
	cout<<"\n creaLista: dimensione: "<<dimensione<<" - primo: "<<primo<<" - lunghezza: "<<lunghezza<<"\n\n"<<endl;
}

template <class T>
bool Lista<T> ::listaVuota()const{
   	return (lunghezza==0);
}
   
template <class T>
void Lista<T>::scriviLista(tipoelem a,posizione p){
   	if((0 < p) && (p <= lunghezza+1))
       elementi[p-1].scriviCella(a,p-1);
}
   
template <class T> typename
Lista<T>::tipoelem Lista<T>::leggiLista(posizione p) const {
	if((0 < p) && (p <= lunghezza+1))
		return elementi[p-1].leggiCella();
	else 
		return p;
}

template <class T> typename
Lista<T>::posizione Lista<T>::primoLista()const{
   	return primo;
}

template <class T> typename
Lista<T>::posizione Lista<T>::ultimoLista() const{
    typename Lista<T>::posizione pos;
    for(pos=primo; !fineLista(elementi[pos].getSuccessivo()); pos=succLista(pos)){
            pos=elementi[pos].getSuccessivo();
    }
   	return pos;
}

template <class T>
bool Lista<T>::fineLista(posizione p) const{
   	if((0 < p) && (p <= lunghezza+1))
       return (p==lunghezza+1);
    else 
		return false;
}

template <class T> typename
Lista<T>::posizione Lista<T>::succLista(posizione p) const {
    if((0 < p) && (p <= lunghezza+1))		
   		return elementi[p].getSuccessivo();
    else{
      	cout<<"\n Non ci sono altri elementi";
      	return p;
	}
}

template <class T> typename
Lista<T>::posizione Lista<T>::predLista(posizione p) const {
     typename Lista<T>::posizione pos;    
    if((1 < p) && (p <= lunghezza+1)){
	   for(pos=primo; elementi[pos].getSuccessivo()<p;pos=succLista(pos)){
            pos=elementi[pos].getSuccessivo();
       }
       return pos;
    }
    else
    	return p;
}
	
template <class T>
void Lista<T>:: insLista(tipoelem a,posizione pv){
     typename Lista<T>::posizione pos; 

	 cout<<"\ninsLista: tipoelem a: "<<a<<" - posizione pv: "<<pv<<"\n"<<endl;
	 cout<<"\ninsLista: dimensione: "<<dimensione<<" - primo: "<<primo<<" - lunghezza: "<<lunghezza<<"\n"<<endl;
     if (lunghezza == dimensione){
         cout<<"\nAUMENTA DIMENSIONE VETTORE LISTA\n"<<endl;
         cambiaDimensione();
     }
     else
         cout<<"\ninserisce elemento\n"<<endl;

	 if((primo == ERR)){
		cout<<"\nprimo = ERR\n"<<endl;
        primo=pv;
		elementi[0].scriviCella(a,pv);//scritto primo elemento della lista
      }
      else{
            cout<<"\nprimo <> ERR\n"<<endl;
            // trova ultima posizione, scorrendo tutta la lista
            for (pos=primo; !fineLista(pos); pos=succLista(pos))
            {}
            pv=elementi[pos].getSuccessivo();
            lunghezza++;  //incremento di conseguenza la variabile lunghezza
      }
}
	
template <class T>
void Lista<T>::cancLista(posizione p){
     if((0 < p) && (p <= lunghezza+1))
		if(!listaVuota()){
			//controllo se l'operazione è effettivamente eseguita su lista non vuota
           	elementi[predLista(p)].setSuccessivo(elementi[p].getSuccessivo());
            lunghezza--;//decremento di conseguenza la variabile lunghezza
   		}
}

template<class T>
void Lista<T>::cambiaDimensione(){
	cout<<"\ninizio cambiaDimensione\n"<<endl;
    int  oldDim;
    CellaListaCur<T> * elemTemp;
   
    oldDim = dimensione;
    dimensione = dimensione *2;
    cout<<"\nprima di inizializzare elemTemp \n"<<endl;
    elemTemp = new  CellaListaCur<T> [dimensione];
    cout<<"\nprima del for \n"<<endl;

    for (int i=0; i<oldDim; i++)
		elemTemp[i]= elementi[i];
    cout<<"\ndopo del for \n"<<endl;
    //delete [] elementi;
    elementi = elemTemp;
   
}

/* operatore di assegnamento */
template<class T> 
Lista<T>& Lista<T>::operator=(const Lista<T>& l){
         if (this != &l){   // attenzione agli autoassegnamenti: l = l 
                 lunghezza = l.lunghezza;
                 //delete this.elementi;
                 for (int i=0; i<dimensione; i++)
                         elementi[i] = l.elementi[i];
         }
         return *this;
}

/* operatore di test di uguaglianza */
template<class T>
bool Lista<T>::operator==(const Lista<T> &l) const{
	if (l.lunghezza != this.lunghezza)
		return false;
    for (int i=0; i<dimensione; i++)
		if (this.elementi[i].leggiCella() != l.elementi[i].leggiCella())
			return false;
    return true;
}

#endif


infine il main.cpp
#include "stdafx.h"
#include <cstdlib>
#include <stdlib.h>
#include <iostream>
#include "ListaCur.h"

void wait(char *);

int _tmain(int argc, _TCHAR* argv[])
{
	Lista<int> dati;
	cout<<"\nprima dei setLista nel main\n\n"<<endl;
	dati.setLista();
    dati.printLista();

    wait("\n\n Programma in stand by\n per continuare digita [Y]+[invio]: ");
 
    system("pause");
    return EXIT_SUCCESS;
}

void wait(char *msg){
   	char stop='?';
    cout<<msg;
    while(stop!='y' && stop!='Y')
      	cin>>stop;
}

aaa
03/01/11 19:30
se utilizzi PrimoLista all'interno dello scope di ListaLineare inevitabilmente verrà utilizzata la funzione PrimoLista virtual di ListaLineare...quindi una funzione che non ha istruzioni al suo interno...prova a cambiare lo scope della funzione, esplicitandolo...
04/01/11 8:15
mannhe
scusa cosa intendi con cambiare lo scope della funzione?
PrimoLista() in ListaLineare è una funzione virtuale pura, che si lega direttamente a come è implementata la lista, ed è per questo che ha il codice definito nella classe che implementa la lista ossia ListaCur.
Ultima modifica effettuata da mannhe 04/01/11 8:16
aaa