Problema con le classi

di il
2 risposte

Problema con le classi

Salve a tutti, questo è il mio primo post.
Ho dei problemi con un codice C++, in particolare, al momento della compilazione del file list_linear_int.h mi riporta l'errore "expected template-name before '<' token". Il codice è il seguente e la classe base Linear_list è definita all'interno del file header linear_list.h. Tengo a precisare inoltre che il nome della classe non è errato.

list_linear_int:
#ifndef _LIST_LINEAR_INT_H
#define _LIST_LINEAR_INT_H

#include "linear_list.h"
#include "list_vector.h"




template<class P >
class list_linear_int : public Linear_list<int, P>{
      public: 
              list_linear_int();
              //typedef P position;
              
              //funzioni di servizio
              void move_min_max();
};

//----------------------------- MOVE_MIN_MAX -----------------------------------
template <class P>
void list_linear_int<P>::move_min_max(){
     
     //dati locali
     int dimensione = size();
     position pos_min, pos_max, fine, pos;
     value_type = elem;
     int i=0, min, max;
     
     min = max = read(pos_min=pos_max=begin());
     while (!end(pos)){
         pos = next(pos);
         elem = read(pos);
         if (min > elem){ min = elem; pos_min = pos}
         if (max < elem){ max = elem; pos_max = pos}
     }//fine for
     exchange(pos, pos_max);
     exchange(begin, pos_min);    
}//fine move_min_max 

#endif
linear_list.h:

#ifndef _LISTALIN_H
#define _LISTALIN_H

#include <iostream>
#include "list_linear_int.h"

using std::cout;
using std::endl;
using std::ostream;

// classe astratta listaLinare
template< class T, class P >
class Linear_list{
 public:
	typedef T value_type;   // the type of object, T, stored in the list
	typedef P position;
	
	// operators
	virtual void create() = 0;
	virtual bool empty() const = 0; // true if the list's size is 0
	virtual value_type read(position) const = 0;
	virtual void write(const value_type & x, position p) = 0; // write x at position p
	virtual position begin() const = 0;  // returns a position pointing to the beginning of the list
	virtual bool end(position) const = 0; // returns a position pointing to the end of the list
	virtual position next(position) const = 0; // returns the next position
	virtual position previous(position) const = 0; // return the previous position
	virtual void insert(const value_type &, position) = 0; // insert an element 
	virtual void erase(position) = 0; // ersaes the element at position pos
	//virtual bool operator!=(const Linear_list<T,P> &l);
	
	// funzioni di servizio
	//friend ostream& operator<< <T,P>(ostream&, const Linear_list<T,P>&);

	/* Altre funzioni di servizio implementabili */
	
		virtual int size() const;  // returns the size of the list
		virtual void inverti();  //inverte il contenuto di una lista
	    virtual bool palindroma();  //stabilisce se una funzione è palindroma
	    virtual void clear(); // erases all the elements
	    virtual int num_elements(position,position); //numero di elementi tra due posizioni
	    virtual void exchange (position, position); //scambia gli elementi tra due posizioni
	    virtual void move_min_max() = 0;//{cout << "ciao" <<endl;}; //sposta il minimo all'inizio e il massimo alla fine
	/*	virtual void push_front(const value_type &); // insert a new element at the beginning
		virtual void push_back(const value_type &); // insert a new element at the end
		virtual void pop_front(); // removes the first element
		virtual void pop_back(); // removes the last element
	*/
	

};

/* sovraccarica <<. Attenzione se il tipo restituito da read non è primitivo, allora
 * anche per questo tipo bisogna sovraccaricare l'operatore << 
 */
template< class T, class P >
ostream& operator<<(ostream& os, const Linear_list<T,P> &l){
	typename Linear_list<T,P>::position p;
	p = l.begin();
	cout << "[";
	while (!l.end(p)){
		if (p != l.begin())
			cout << ", " << l.read(p);
		else
			cout << l.read(p);
		p = l.next(p);
	}
	cout << "]" << endl;
	return os;
}

//----------------------------------- SIZE -------------------------------------
template< class T, class P >
int Linear_list<T,P>::size() const{
    
   //dati locali
   position pos;
   int cont;
   
   cont = 0;
   if (!empty()){
         pos = begin();
         while (!(end(pos))){
               cont++;
               pos = next(pos);
         }
   }
   return cont;
}//fine size()

//---------------------------------- INVERTI -----------------------------------
template< class T, class P >
void Linear_list<T,P>::inverti() {
     
   //dati locali
   position inizio, fine, pos;
   int dimensione = size();
   int i=0;
   value_type temp;

   if (!empty()){
         inizio = fine = begin();
         while (!end(next(fine))){
               fine = next(fine);
         }//fine while
         while (i < dimensione/2){
               temp = read(fine);
               write (read(inizio), fine);
               write (temp, inizio);
               fine = previous(fine);
               inizio = next(inizio);
               i++;
         }//fine mentre
   }//fine se   
}//fine push_front


//--------------------------------- PALINDROMA ---------------------------------
template< class T, class P >
bool Linear_list<T,P>::palindroma() {
     
     //dati locali
     bool is_palindroma;
     position inizio, fine;
     int i=0;
     int dimensione = size();
     
     is_palindroma = true;
     if (!empty()){
         inizio = fine = begin();
         while (!end(next(fine))){
               fine = next(fine);
         }//fine while
         while ((i < dimensione/2)&&(is_palindroma)){
               if (read(fine) == read(inizio)){
                  fine = previous(fine);
                  inizio = next(inizio);
                  i++;
               }else{
                  is_palindroma = false;
               }//fine se  
         }//fine mentre
     }//fine se
     return is_palindroma;      
}//fine palindroma

//-------------------------- SOVRACCARICO OPERATORE != -------------------------
template< class T, class P >
bool operator!=(const Linear_list<T,P> &l1, const Linear_list<T,P> &l2){
     
     typedef typename Linear_list<T,P>::position position;
     
     //dati locali
     position pos1, pos2;
     int i=0;
     
     if (l1.size() != l2.size())
          return true;
     else{
          pos1=l1.begin();
          pos2=l2.begin();
          for (i=0; i<l1.size(); i++){
              if (l1.read(pos1) != l2.read(pos2))
                   return true;
              else{
                   pos1 = l1.next(pos1);
                   pos2 = l2.next(pos2);
              }//fine se
          }//fine for
     }//fine se
     return false;
}//fine operatore !=


//----------------------------------- CLEAR ------------------------------------
template< class T, class P >
void Linear_list<T,P>::clear() {
     
     //dati locali
     position pos, pross, fine;
     int i=0;
     int dimensione = size();
     
     if (!empty()){
        pos = fine = begin();
        while (!end(next(fine))){
               fine = next(fine);
        }//fine while
        while (i < dimensione){
              pos = previous(fine);
              erase(fine);
              fine = pos;
              i++;
        }
     }//fine se     
}//fine palindroma


//------------------------------ NUM_ELEMENTS ----------------------------------
template <class T, class P>
int Linear_list<T,P>::num_elements(position p1, position p2){
    
    //dati locali
    int cont=0;
    position pos = begin();
    
    while ((pos != p1) && (pos != p2) && !end(pos)) pos = next(pos);
    if (end(next(pos))) return 0; //le due posizioni in input non sono corrette
    else{
         //determino la prima e seconda posizione (cioè l'ordine) 
         if (pos == p2){
            pos = p1;
            p1 = p2;
            p2 = pos;
         }//fine se
    }
    p1 = next(p1);
    while ((p1 != p2)&&(!end(p1))){
          cont++;
          p1=next(p1);
    }//fine mentre
    return cont;
}//fine num_elements


//-------------------------------- EXCHANGE ------------------------------------
template <class T, class P>
void Linear_list<T,P>::exchange(position p1, position p2){
     
     //dati locali
     value_type temp, temp2;
     
     
     temp = read(p1);
     if ((temp >= 0)&&(read(p2) >= 0)){ //controllo che p1 e p2 siano indirizzi validi
        write (read(p2), p1);    
        write (temp, p2);
     }//fine se
}//fine exchange

#endif // _LISTALIN_H
Inoltre, nel file List_vector.h (che riporto di seguito) è definita un'altra classe derivata dalla classe Linear_list:

#ifndef _LISTAVT_H
#define _LISTAVT_H

#include "linear_list.h"

// classe Lista
template< class T >
class List_vector : public Linear_list<T, int>{
 public:
	typedef typename Linear_list<T, int>::value_type value_type;
	typedef typename Linear_list<T, int>::position position;

	// costruttori
	List_vector();    
	List_vector(int); 
	// costruttore per copia
	List_vector(const List_vector<T>& ); 
	//distruttore
	~List_vector();   
	
	// operatori
	void create();
	bool empty() const;
	value_type read(position) const;
	void write(const value_type &, position);
	position begin() const;
	bool end(position) const;
	position next(position) const;
	position previous(position) const;
	void insert(const value_type &, position);
	void erase(position);
	//virtual void move_min_max() =0;//{cout << "ciao" <<endl;};

	// sovraccarico di operatori
	List_vector<T>& operator=(const List_vector<T>&); // the assignment operator
	bool operator==(const List_vector<T> &) const; // tests two list for equality

 private:
	void change_dimension_(T*& , int , int );
	value_type* elements_;
	int length_; // the length of the list
	int array_dimension_; // array's dimension
};

// costruttore
template< class T >
List_vector< T >::List_vector() {
  array_dimension_ = 10;
  this->create();
}

// costruttore
template< class T >
List_vector< T >::List_vector(int dim){
  array_dimension_ = dim;
  this->create();
}

/* Il costruttore per copia effettua una copia o clone di un oggetto.  
 * Questo costruttore viene invocato, per esempio, quando un oggetto viene passato 
 * per valore ad una funzione o quando una funzione restituisce un oggetto. 
 */
template< class T >
List_vector< T >::List_vector(const List_vector<T>& Lista) {
  this->array_dimension_ = Lista.array_dimension_;
  this->length_ = Lista.length_;
  this->elements_ = new T[array_dimension_];
  for (int i=0; i<Lista.array_dimension_; i++)
     this->elements_[i] = Lista.elements_[i];
}

// distruttore
template< class T >
List_vector< T >::~List_vector(){
	delete elements_;
}

// operatori
template< class T >
void List_vector< T >::create(){
  this->elements_ = new T[array_dimension_];
  this->length_ = 0;
}

template< class T >
bool List_vector< T >::empty() const {
    return(length_ == 0);
}

template< class T >
typename List_vector< T >::position List_vector< T >::begin() const {
	return(1); // e quindi pos(1)=pos(n+1) se la lista -Ah vuota (n=0)
}

template< class T >
typename List_vector< T >::position List_vector< T >::next(position p) const {
	if ( (0 < p) && (p < length_+1)) // precondizione
		return(p+1);
	else
		return(p);
}

template< class T >
typename List_vector< T >::position List_vector< T >::previous(position p) const {
	if ( (1 < p) && (p < length_+1)) // precondizione
		return(p-1);
	else
		return(p);
}

template< class T >
bool List_vector< T >::end(position p) const {
	if ( (0 < p) && (p <= length_+1)) // precondizione
		return( p == length_+1);
	else
		return(false);
}

template< class T >
typename List_vector< T >::value_type List_vector< T >::read(position p) const {
	if ( (0 < p) && (p < length_+1)) // precondizione
		return(elements_[p-1]);
	else return -1;
}

template< class T >
void List_vector< T >::write(const value_type &a, position p) {
  if ( (0 < p) && (p < length_+1)) // precondizione
    elements_[p-1] = a;
}

template< class T >
void List_vector< T >::insert(const value_type &a, position p){
  if (length_ == array_dimension_){
    change_dimension_(elements_, array_dimension_, array_dimension_ * 2);
    array_dimension_ = array_dimension_ * 2;
  }
  if ( (0 < p) && (p <= length_+1)) { // precondizione
		for (int i=length_; i>=p; i--)
			elements_[i] = elements_[i-1];
		elements_[p-1]=a;
		length_++;
	}
}

template< class T >
void List_vector< T >::erase(position p){
  if ( (0 < p) && ( p < length_ + 1)) // precondizione
    if (!empty()) {
			for (int i=p-1;i<(length_-1);i++)
				elements_[i]=elements_[i+1];
			length_--;
		}
}

template<class T>
void List_vector< T >::change_dimension_(T*& a, int vecchiaDim, int nuovaDim){

  T* temp = new T[nuovaDim];
  int number;
  if (vecchiaDim < nuovaDim) 
     number = vecchiaDim;
  else
     number = nuovaDim;
  for (int i=0; i<number; i++)
     temp[i]=a[i];
  delete [] a;
  a = temp;
}

/* operatore di assegnamento */
template<class T>
List_vector<T>& List_vector<T>::operator=(const List_vector<T>& l){
	if (this != &l){   // attenzione agli autoassegnamenti: l = l 
		this->array_dimension_ = l.array_dimension_;
		this->length_ = l.length_;
		delete this->elements_;
		this->elements_ = new T[array_dimension_];
		for (int i=0; i<l.array_dimension_; i++)
			this->elements_[i] = l.elements_[i];
	}
	return *this;
}

/* operatore di test di uguaglianza */
template<class T>
bool List_vector<T>::operator==(const List_vector<T> &l) const{
	if (l.length_ != this->length_)
		return false;
  for (int i=0; i<this->array_dimension_; i++)
		if (this->elements_[i] != l.elements_[i])
			return false;
	return true;
}


#endif // _LISTAVT_H

2 Risposte

  • Re: Problema con le classi

    Io vedo un riferimento circolare
    linear_list.h che include list_linear_int.h e viceversa.
  • Re: Problema con le classi

    Si ma comunque non è quello il problema perchè utilizzando il costrutto #ifndef....#define....#endif un file d'intestazione viene incluso una sola volta....
Devi accedere o registrarti per scrivere nel forum
2 risposte