Domanda sulla compilazione separata di un template

di il
3 risposte

Domanda sulla compilazione separata di un template

Salve a tutti,
ho una domanda sui template. Ho fatto un esercizio su un template di classe adottando la compilazione separata ossia inserendo la dichiarazione del template di classe nel file .h, le definizioni nel file .cpp, eppoi ho eseguito il main in un altro file .cpp. In questo modo però il programma non parte! Il compilatore mi dice undefined reference to... Invece mettendo nel file .h sia le dichiarazioni che le definizioni dei metodi del template di classe il tutto parte senza errori. Come mai? C'è un modo per far sì che io possa fare i tre file separati e poi compilarli? Grazie

3 Risposte

  • Re: Domanda sulla compilazione separata di un template

    Guarda la voce Template e modularità:
    http://www.bo.cnr.it/corsi-di-informatica/corsoCstandard/Lezioni/33Template.html

    p.s.: Ma nei altri post non rispondi più?
  • Re: Domanda sulla compilazione separata di un template

    Grazie Skynet. Alla fine bisogna implementare sia dichiarazioni che definizioni del template nello stesso header file proprio perchè esso è istanziato staticamente. Ho provato con export ma il compilatore dev c++ non me la riconosce come parola chiave. Devo provare con eclipse...Un ultima domanda ma nell' header file ci posso mettere sempre le istruzioni #ifndef #define di precompilazione oppure meglio di no! Ad esempio questa classe pila template è scritta bene? (file Pila.h)
    
    #ifndef PILA_H
    #define PILA_H
    
    using namespace std;
    
    template <class Tipo>
    class Pila
    {
          public:
                  Pila();
                  Pila (const unsigned int n); // costruttore che setta il massimo num. di elementi
                  ~Pila();
                  void Svuotare();
                  void Immettere (const Tipo& x);
                  Tipo Estrarre();
                  Tipo Cima() const;
                  bool Vuota() const;
                  bool Piena() const;
                  void Stampa();
          private:
                  unsigned int max; // numero massimo di elementi che può contenere la pila
                  unsigned int cima; // puntatore alla cima della pila
                  Tipo *valore; // array dinamico di elementi di tipo Tipo
    };
    
    template <class Tipo>
    Pila <Tipo> :: Pila() : max(100), cima(0), valore(new Tipo[max]) {}
    
    template <class Tipo>
    Pila <Tipo> :: Pila(const unsigned int n) : max(n), cima(0), valore(new Tipo[max]) {}
    
    template <class Tipo>
    Pila <Tipo> :: ~Pila() { delete [] valore; }
    
    template <class Tipo>
    void Pila <Tipo> :: Svuotare() { cima = 0; }
    
    template <class Tipo>
    void Pila <Tipo> :: Immettere(const Tipo& x) 
    {
         if (Piena())
            cout << "Pila piena" << endl;
         else
         {
             valore[cima] = x;
             cima++;
         } 
    }
    
    template <class Tipo>
    Tipo Pila <Tipo> :: Estrarre() 
    {
         Tipo aux;
         if (Vuota())
            cout << "Pila vuota" << endl;
         else
         {
             aux = valore[cima];
             cima--;
             return aux;
         }
    }
    
    template <class Tipo>
    Tipo Pila <Tipo> :: Cima() const { return valore[cima]; }
    
    template <class Tipo>
    bool Pila <Tipo> :: Vuota() const { return (cima == 0); }
    
    template <class Tipo>
    bool Pila <Tipo> :: Piena() const { return (cima >= max); }
    
    template <class Tipo>
    void Pila <Tipo> :: Stampa()
    {
         for (int i = 0; i < max; i++)
             cout << valore[i] << " ";
             
         cout << endl;
    }  
    
    #endif               
    
    File main.cpp
    
    #include <iostream>
    #include <cstdlib>
    #include "Pila.h"
    
    using namespace std;
    
    int main ()
    {
           Pila <int> p(5); // richiama il costruttore che imposta il max a 5
        
           p.Immettere(1);
           p.Immettere(5);
           p.Immettere(7);
           p.Immettere(9);
           cout << "Lista: ";
           p.Stampa();
           cout << "Estraggo in testa..";
           p.Estrarre();
           p.Stampa();
           cout << "Testa della pila: ";
           cout << p.Cima() << endl;
        
           system ("pause");
           return 0;
    }
    
    Visto che ci sono il programma che ho fatto mi stampa 0 all'ultima posizione mentre voglio che non mi stampi niente se il vettore non è completo. E soprattutto la funzione Estrarre (pop) non mi riduce il vettore. Chiedo lumi. Grazie..Per gli altri post è tutto chiaro skynet...
  • Re: Domanda sulla compilazione separata di un template

    Nei header non usare mai "using namespace" cerca sempre di usare la forma lunga "std:: ....."
    Puoi usare tutti le direttive processore che ti servono (#define, #ifndef ecc...)
    Vuota e Piena li puoi fare una in relazione dell'altra ovvero
    
    template <class Tipo>
    bool Pila <Tipo> :: Vuota() const { return (cima == 0); }
    
    .....
    template <class Tipo>
    bool Pila <Tipo> :: Piena() const { return !Vuota(); }
    
    il fatto che la funzione di estrazione non ti elimina l'elemento può essere anche un bene nel senso che non hai bisogno di eliminare fisicamente il posto occupato dall'elemento, semplicemente lo marchi come non usato. (Anche la classe std::vector fa così). Alla richiesta di una funzione specifica (vedi std::vector::shrink_to_fit implementata nel C++11) puoi creare una funzione tipo questa.
Devi accedere o registrarti per scrivere nel forum
3 risposte