Newsgroup: it.comp.lang.c++
Titolo: Perchè non mi linka?

Vi pongo una questione: perchč i seguenti 3 files vengono compilati con 0
errori, e poi mi danno errore in fase di linkaggio?
// File Coda.h
#ifndef CODA_H
#define CODA_H
template <class Tipo>
struct item
{ Tipo val;
  item* next;
};
template <class Tipo>
class Coda
{public:
  Coda();
  ~Coda() { Distruggi(front); }
  Coda& operator=(const Coda&);
  Coda(const Coda&);
  bool EstVuota() { return front == NULL; }
  void OutCoda();
  void InCoda(Tipo);
  Tipo Primo() { return front->val; }
 private:
  item<Tipo>* front;
  item<Tipo>* back;
  void Distruggi(item<Tipo>*);
  item<Tipo>* Copia(item<Tipo>*);
};
#endif
// File Coda.cpp
#include "Coda.h"
template <class Tipo>
Coda<Tipo>::Coda()
{ front = NULL;
  back = NULL;
}
template <class Tipo>
Coda<Tipo>& Coda<Tipo>::operator=(const Coda<Tipo>& c)
{ if (this == &c) return *this;
  if (c.front != NULL)
    { item<Tipo>* pt = front;
      front = Copia(c.front);
      Distruggi(pt);
      back = front;
      while (back->next != NULL)
        back = back->next;
    }
  else
    { front = NULL;
      back = NULL;
    }
}
template <class Tipo>
Coda<Tipo>::Coda(const Coda<Tipo>& c)
{ if (c.front != NULL)
  { front = Copia(c.front);
    back = front;
    while (back->next != NULL)
      back = back->next;
  }
  else
    { front = NULL;
      back = NULL;
    }
}
template <class Tipo>
void Coda<Tipo>::InCoda(Tipo elem)
{ item<Tipo>* pt = new item<Tipo>;
  pt->val = elem;
  pt->next = NULL;
  if (front == NULL)
    { front = pt;
      back = pt;
    }
  else
    { back->next = pt;
      back = pt;
    }
}
template <class Tipo>
void Coda<Tipo>::OutCoda()
{ item<Tipo>* pt = front;
  front = front->next;
  delete pt;
}
template <class Tipo>
void Coda<Tipo>::Distruggi(item<Tipo>* pt)
{ if (pt != NULL)
    { Distruggi(pt->next);
      delete pt;
    }
}
template <class Tipo>
item<Tipo>* Coda<Tipo>::Copia(item<Tipo>* p)
{ if (p != NULL)
    { item<Tipo>* q = new item<Tipo>;
      q->val = p->val;
      q->next = Copia(p->next);
      return q;
    }
  else return NULL;
}
file://File MainCoda.cpp
#include "CODA.H"
#include <iostream.h>
void main()
{
 Coda<int> c;
 c.CodaVuota();
 cout<<"Inserisci Coda (-1 per finire): ";
 int temp;
 while (temp!= -1)
 {
  cin>>temp;
  c.InCoda(temp);
 }
 c.StampaCoda();
}

Un classico...
La risposta e` sulle FAQ (
www.programmazione.it
)
La domanda numero 10 per la precisione.
Paolo
--------------------------------------------------
  Paolo Marotta
  Computer Science, University of Pisa
  home:   
http://www.cli.di.unipi.it/~marotta
--------------------------------------------------

 << CUT >>
Teoricamente dovresti usare export in coda.cpp per far sapere al compilatore
che la definizione dei template è esportatata (in modo che quando utilizzi
coda.h in main il compilatore riesca a trovare la definizione dei template).
In pratica il Visul C++ non sa nemmeno cosa sia export e quindi devi inserire
la definizione dei template all'interno della stessa unità di compilazione
che li usa (ad occhio, per esempio, direi che se inserisci #include
"coda.cpp" in main.cpp dovrebbe funzionare).
Ciao FBF.

 errori, e poi mi danno errore in fase di linkaggio?
[CUT]
Il linguaggio non prevede la risoluzione dei template con la compilazione
separata. L'unico modo per farlo linkare, è affidarsi agli strumenti che
mette a disposizione il compilatore, attraverso le direttive #pragma in
genere.
Ad esempio, se usi Turbo C++ v3.0 della Borland dovresti:
1) aggiungere nell'header, prima di #endif la riga
    #pragma option -Jgx
2) aggiungere nel file d'implementazione subito dopo l'include
    #pragma option -Jgd
poi dovrai usare tanti typedef quante saranno le specializzazioni che
intendi usare. Nel tuo caso, usi nel file MainCoda.cpp solo Coda<int> per
cui in Coda.cpp dopo il pragma dovrai aggiungere
    typedef Coda<int> Codaint;
in realtà ciò che segue lo puoi chiamare come ti pare, è solo una
dichiarazione che serve al collegatore.
Se tu avessi usato anche una coda di double, dovevi aggiungere anche una
riga del tipo
    typedef Coda<double> Codadouble;
e così via, per ogni tipo che intendi usare. Tutto il resto del codice va
bene così com'è.
--
  Jerle Shannara
Togli NO SPAM dall'email

 wrote in message
069bjss29be0v2mjf...@4ax.com...


Grazie!!! Veramente non so come ringraziarti! Quando ho messo il messaggio
sul newsgroup, non speravo nemmeno di avere una risposta cosi esauriente(a
dir la verità non speravo nemmeno di avere una risposta!). Sto preparando un
esame ed erano due giorni che stavo sbattendo la testa su 3 diversi
compilatori!
Grazie ancora!
Jerle Shannara <alfs...@SPAMinwind.it> wrote in message
8h5upn$rok$1...@sirmdpsin16.inwind.it...



