Visualizzazione dei risultati da 1 a 8 su 8
  1. #1

    [C++] Dichiarazione anticipata con classe template - problema

    Salve, ho un problema che vorrei esporvi. Ho fatto diverse prove e credo di aver individuato la causa.

    Il codice è questo:

    codice:
    #ifndef LISTA_PUNTATORI_H
    #define LISTA_PUNTATORI_H
    
    
    
    template <typename T> class Lista_puntatori {
    
    // blocco di interesse---------------------
    struct nodo {
       T elemento;
       nodo * successivo;
       nodo * precedente;
    }; 
    
    typedef nodo * posizione;
    
    //fine blocco di interesse------------------
    
    public:
          
       Lista_puntatori();
       ~Lista_puntatori();
       
       void creaLista();
       void insLista(T, posizione);
       void scriviLista(T, posizione);
       void cancLista(posizione);
       
       bool listaVuota();
       bool fineLista(posizione);
       
       posizione primoLista();
       posizione succLista(posizione);
       posizione precLista(posizione);
       
       T leggiLista(posizione);
       
    private:
       posizione primo;
    };
    
    
    template <class T> Lista_puntatori<T>::Lista_puntatori(){
       creaLista();
    };
    
    template <class T> Lista_puntatori<T>::~Lista_puntatori(){
       posizione p;
       while (primo != NULL){
          p = primo;
          primo = primo->successivo;
          delete p;
       }         
    };
    
    template <class T> void Lista_puntatori<T>::creaLista(){
       primo = NULL;
    };
    
    template <class T> void Lista_puntatori<T>::insLista(T elem, posizione p){
       posizione temp;
       temp->elemento = elem;
       temp->successivo = p;
       
       if (primo == p){
          temp->precedente = NULL;
          primo = temp;          
       } else {
         temp->precedente = p->precedente;
         precLista(p)->successivo = temp;
         p->precedente = temp;
       }      
    };
    
    template <class T> void Lista_puntatori<T>::scriviLista(T elem, posizione p){
       if ((primo != NULL) && (p != NULL)){
          p->elemento = elem;
       }
    };
    
    template <class T> void Lista_puntatori<T>::cancLista(posizione p){
       if ((p != NULL) && (primo != NULL)){
          precLista(p)->successivo = p->successivo;
          succLista(p)->precedente = p->precedente;
          delete p;
       }
    };
    
    template <class T> bool Lista_puntatori<T>::listaVuota(){
       return (primo == NULL);
    };
    
    
    template <class T> bool Lista_puntatori<T>::fineLista(posizione p){
       return (p == NULL);
    };
    
    template <class T> posizione Lista_puntatori<T>::primoLista(){
       return primo;         
    };
    
    template <class T> posizione Lista_puntatori<T>::succLista(posizione p){
       if (p != NULL)
          return p->successivo;
        else 
           return NULL;
    };
    
    template <class T> posizione Lista_puntatori<T>::precLista(posizione p){
       if (p != NULL)
          return p->precedente;
        else 
           return NULL;
    };
    
    template <class T> T Lista_puntatori<T>::leggiLista(posizione p){
          if (p != NULL)
          return p->elemento;
        else 
           return NULL;
    };
    
    #endif
    Il problema principale è: in fase di compilazione, mi da errore "expected constructor, destructor, or type conversion before "Lista_puntatori"" e "expected ';' before "Lista_puntatori"" sulle righe 98, 102, e 108, che sono le implementazioni delle funzioni primoLista(), succLista() e precLista().

    Per quanto ne ho capito, il problema deriva dalla definizione di "posizione" (infatti tutte quelle funzioni dovrebbero restituire un dato di tipo posizione).
    La causa dovrebbe essere il fatto che nodo e posizione sono definiti dopo la dichiarazione della classe (dopo la 3a riga in pratica, commentato come "blocco di interesse"), mentre dovrebbero essere posizionati prima della 3a riga.

    Per risolvere questo problema, ho provato a portare il "blocco di interesse" prima della 3a riga.
    Il risultato è che, giustamente, lì non sa ancora cos'è T (utilizzata nello struct) e quindi se provo in quest'altro modo dà errore: 'T' does not name a type.

    codice:
    #ifndef LISTA_PUNTATORI_H
    #define LISTA_PUNTATORI_H
    
    // blocco di interesse---------------------
    struct nodo {
       T elemento;
       nodo * successivo;
       nodo * precedente;
    }; 
    
    typedef nodo * posizione;
    
    //fine blocco di interesse------------------
    
    
    template <typename T> class Lista_puntatori {
    Per far conoscere T in quel punto, dovrei fare una dichiarazione anticipata della classe, ma anche se provo a fare:
    codice:
    #ifndef LISTA_PUNTATORI_H
    #define LISTA_PUNTATORI_H
    template <typename T> class Lista_puntatori;
    // blocco di interesse---------------------
    struct nodo {
       T elemento;
       nodo * successivo;
       nodo * precedente;
    }; 
    
    typedef nodo * posizione;
    
    //fine blocco di interesse------------------
    
    
    template <typename T> class Lista_puntatori {
    mi dice sempre 'T' does not name a type.

    Ora, come potrei fare per far funzionare sto codice?
    Avete qualche idea?

    Grazie.

  2. #2
    Utente di HTML.it L'avatar di XWolverineX
    Registrato dal
    Aug 2005
    residenza
    Prague
    Messaggi
    2,563
    Non puoi dichiarare la struttura dopo la classe?
    "Se proprio devono piratare, almeno piratino il nostro." (Bill Gates)

    "Non è possibile che 2 istituzioni statali mi mettano esami nello stesso giorno." (XWolverineX)

    http://xvincentx.netsons.org/programBlog

  3. #3
    No, perchè la variabile "posizione" è un puntatore allo struct e viene utilizzato all'interno della classe.
    Quindi ho bisogno di avere "posizione" subito.

    ps: sono decisamente alle prime armi con c++.

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se non ho visto male c'è una grafa di troppo:
    codice:
    template <typename T> class Lista_puntatori {
    // blocco di interesse---------------------
    Comunque io modificherei il codice in questo modo:

    codice:
    // blocco di interesse---------------------
    template <typename U>
    struct nodo {
       nodo(nodo* n1=0,nodo* n2=0) : successivo(n1),precedente(n2) {} // azzera in automatico i puntatori.
       U elemento;
       nodo * successivo;
       nodo * precedente;
    }; 
    
    
    //fine blocco di interesse------------------
    template <typename T> class Lista_puntatori {
    
    private:
       typedef nodo<T>* posizione;
    public:
          
       Lista_puntatori();
       ~Lista_puntatori();
       
       void creaLista();
       void insLista(T, posizione);
       void scriviLista(T, posizione);
       void cancLista(posizione);
       
       bool listaVuota();
       bool fineLista(posizione);
       
       posizione primoLista();
       posizione succLista(posizione);
       posizione precLista(posizione);
       
       T leggiLista(posizione);
       
    private:
       posizione primo;
    };
    Poi ci sono errori concettuali nelle varie funzioni.
    CreaLista è inutile se serve ad azzerare solo un puntatore, per quello ci può pensare il costruttore della classe, dovrebbe invece controllare se il puntatore è allocato o no e nel caso non lo sia, allocare la memoria per "primo", se invece "primo" è già allocato dovrebbe resettare la lista precedente per crearne una nuova.

  5. #5
    Non ho capito come mai quella graffa sia di troppo..è quella di apertura della classe..

    Comunque ho provato ad effettuare le modifiche che mi hai suggerito (grazie mille ), ma niente, sempre lo stesso errore:

    Linea 94 expected constructor, destructor, or type conversion before "Lista_puntatori"
    Linea 94 expected ';' before "Lista_puntatori"
    Linea 98 expected constructor, destructor, or type conversion before "Lista_puntatori"
    Linea 98 expected ';' before "Lista_puntatori"
    Linea 105 expected constructor, destructor, or type conversion before "Lista_puntatori"
    Linea 105 expected ';' before "Lista_puntatori"

    le linee sono le seguenti:
    codice:
    template <class T> bool Lista_puntatori<T>::fineLista(posizione p){
       return (p == NULL);
    };
    
    template <class T> posizione Lista_puntatori<T>::primoLista(){ //linea 94
       return primo;         
    };
    
    template <class T> posizione Lista_puntatori<T>::succLista(posizione p){ //linea 98
       if (p != NULL)
          return p->successivo;
        else 
           return NULL;
    };
    
    template <class T> posizione Lista_puntatori<T>::precLista(posizione p){ //linea 105
       if (p != NULL)
          return p->precedente;
        else 
           return NULL;
    };

  6. #6
    se le funzioni le metti all'interno della classe funziona tutto!! E' un problema di scope... ma purtroppo non riesco ad esserti di maggior aiuto..

  7. #7
    Ho trovato una soluzione ma non sono riuscito a capirla ::: Basta che nella definizione della funzione metti typename es :

    codice:
    #include <iostream>
    
    
    template < class T> class Lista {
    
    	struct nodo { 
    		nodo * next; 
    		T info; 
    	};
    
    	typedef nodo * nodo_ptr; 
    
    	nodo_ptr list; 	
    	
    	public: 
    
    	Lista(){ list = NULL;   };
    	~Lista(); 
    	Lista( const Lista&); 	
    
    	T first() { if(list->info) return list->info;}; 
    
    	nodo_ptr get();  
    
    };
    
    template < class T >Lista<T>::~Lista() {
    
    	nodo_ptr temp = list; 
    	
    	while ( list) { 
    		temp = list; 
    		list = list->next; 
    		delete temp; 
    	}
    
    	list  = NULL; 
    
    }
    
    
    template < class T > typename 
    Lista<T>::nodo_ptr Lista<T>::get(){
    	return list;
    }
    ;

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Originariamente inviato da innaig86
    Non ho capito come mai quella graffa sia di troppo..è quella di apertura della classe..
    Pardon, ho visto male.

    Per quanto riguarda il resto.
    Quando si usa una nested class occorre specificare tutto il percorso del nome della variabile, come ha fatto PeppePes88. Il typename è necessario (quando si usa un template) per specificare al compilatore che quello che segue non è una variabile appartente alla classe ma un nome di tipo.

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2026 vBulletin Solutions, Inc. All rights reserved.