Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    32

    Problemi con le superclassi e i metodi virtual

    Salve a tutti
    sto avendo un problema con un programma in C++. L'errore che mi esce è:

    " [Linker error] undefined reference to `vtable for Superclasse' "

    qualcuno sa spiegarmi a cosa si riferisce?

    Il codice è questo:

    Il file lib.h:
    codice:
      #ifndef _LISTAP_H
    #define _LISTAP_H
    #define N 100		//dimensione del vettore
    #include <iostream>
    #include <string>
    using std::string;
    using namespace std;
    
    struct TcomponenteSpazio
    	 {                                
            int elemento;
            int successivo;
            int precedente;
            TcomponenteSpazio()
            {
                elemento=0;
                successivo=precedente=-1;             
            }
    	 };
    	 
    class classe_spazio
    {                   
    private:
        TcomponenteSpazio spazio[N];
        int componenteSpazio_testa;
        int componenteSpazio_coda;
    public:
        classe_spazio();
        int getTesta();
        int getCoda();
        void setCoda(int);
        void setTesta(int);
        inline TcomponenteSpazio & operator[](size_t Index)
        {
            return spazio[Index];
        }
    };
    
    typedef int tipoelem;
    
    //   SUPERCLASSE:
    
    class Superclasse{
                      
                     
                public:
                       typedef int posizione;
                       
                       virtual void crealista();
                       virtual bool listavuota() const;
                       virtual posizione primoLista() const;
                       virtual posizione succlista(posizione) const;
                       virtual posizione preclista(posizione) const;
                       virtual bool finelista(posizione) const;
                       virtual tipoelem leggilista(posizione) const;
                       virtual void scrivilista(tipoelem, posizione);
                       virtual void inslista(tipoelem,posizione);
                       virtual void canclista(posizione p);
                      
                               
          };
          
    /*----------------------------------------------------------------------------*/
    
    class Lista : public Superclasse {
          
      public:	
        /* posizione è un puntatore a cella */
        /* Prototipi degli operatori */
        
        Lista();
        
    
        void crealista();
        bool listavuota() const;
        posizione primoLista() const;
        posizione succlista(posizione) const;
        posizione preclista(posizione) const;
        bool finelista(posizione) const;
        tipoelem leggilista(posizione) const;
        void scrivilista(tipoelem, posizione);
        void inslista(tipoelem,posizione);
        void canclista(posizione p);
     
      private:
        static classe_spazio spazio;
        int testa;
        int coda;
      };
    Il file lib.cpp:
    codice:
    /* Liste: Rappresentazione collegata circolare (con sentinella)
     * realizzata mediante doppi puntatori (o simmetrica)
     */
    
    #include "listap.h"
    /******************************************************************************/
    
    
    /*Metodi classe_spazio*/
    classe_spazio Lista::spazio;
    
    classe_spazio::classe_spazio()
    {
      int i;
      //inizializzo l'elemento 0 e lo collego al primo
      componenteSpazio_testa = 0;
      spazio[0].elemento = 0;
      spazio[0].precedente = -1;
      spazio[0].successivo = 1;
      //inizializzo gli elementi da 1 a N-1 collegandoli tra loro
      for(i=1; i < N-1; i++)
      {
         spazio[i].elemento = 0;
         spazio[i].precedente = i-1;
         spazio[i].successivo = i+1;
      }
      //inizializzo l'N-esimo elemento
      componenteSpazio_coda = i;
      spazio[i].elemento = 0;
      spazio[i].precedente = i-1;
      spazio[i].successivo = -1;
    }
    
    int classe_spazio::getTesta()
    {
        return componenteSpazio_testa;
    }
    
    int classe_spazio::getCoda()
    {
        return componenteSpazio_coda;
    }
    
    void classe_spazio::setCoda(int posizione)
    {
         componenteSpazio_coda = posizione;
    }
    
    void classe_spazio::setTesta(int posizione)
    {
         componenteSpazio_testa = posizione;
    }
    
    /******************************************************************************/
    /*Metodi classe lista*/
    Lista::Lista()
    {
      crealista();
    }
    
    void Lista::crealista()
    {
         int Scoda, Stesta, temp;
         Scoda = spazio.getCoda();
         //Stesta = spazio.getTesta();
        if(Scoda == -1)
        {
          cout << endl << "Errore: Non c'e' spazio per creare la nuova lista" << endl;         
        }
        else
        {
            //Assegna alla coda la posizione
            testa = Scoda;
            //Assegno alla coda la posizione di testa perchè la lsita e' di un solo elemento
            coda = testa;
            spazio.setCoda(spazio[Scoda].precedente);
            temp = spazio[Scoda].precedente;
            spazio[Scoda].precedente = -1;
            spazio[temp].successivo = -1;
        }
        
         
    }
    
    bool Lista::listavuota() const
      {
         bool ritorno;
         if(testa == -1)
         {
           ritorno = true;                          
         }
         else
         {
           ritorno = false;    
         }
         return ritorno;
      }
    
    Lista::posizione Lista::primoLista() const
      {
        return testa;
      }
      
    
    Lista::posizione Lista::succlista(Lista::posizione p) const
      {
         int ele = -1;
        /*Precondizione = La posizione passata non deve essere maggiore del
        numero massimo di elementi del vettore spazio*/
        if((p >= 0) && (p < N))
        {
          ele = spazio[p].successivo;
        }
        return ele;
      }
    
    Lista::posizione Lista::preclista(Lista::posizione p) const
      {
         int ele = -1;
        /*Precondizione = La posizione passata non deve essere maggiore del
        numero massimo di elementi del vettore spazio*/
        if((p >= 0) && (p < N))
        {
          ele = spazio[p].precedente;
        }
        return ele;
    
      }
      
    
    bool Lista::finelista(Lista::posizione p) const
      {
        return (p==coda);
      }
    
    tipoelem Lista::leggilista(posizione p) const
      {
        int ele = -1;
        /*Precondizione = La posizione passata non deve essere maggiore del
        numero massimo di elementi del vettore spazio*/
        if((p >= 0) && (p < N))
        {
          ele = spazio[p].elemento;
        }
        return ele;
      }
    
    void Lista::scrivilista(tipoelem a, posizione p)
    {
      spazio[p].elemento = a;
        /*Precondizione = La posizione passata non deve essere maggiore del
        numero massimo di elementi del vettore spazio*/
        if((p >= 0) && (p < N))
        {
          spazio[p].elemento = a;
        }
    }
    
    void Lista::inslista(tipoelem a, Lista::posizione p)
    {
         /*Precondizione = La posizione passata non deve essere maggiore del
        numero massimo di elementi del vettore spazio*/
       if((p >= 0) && (p < N))
       {
          //Verifico che la lista spazio non è vuota
          if(spazio.getCoda() != -1)
          {
              int NCodaSpazio;
              NCodaSpazio = spazio[spazio.getCoda()].precedente;
              //debug
              //cout << NCodaSpazio << endl;
              
              //Caso in cui sto aggiungendo un elemento in mezzo alla lista
              if(testa != p)
              {
                //Setto i valori del nuovo elemento che sto inserendo in posizione p
                spazio[spazio.getCoda()].elemento = a;
                spazio[spazio.getCoda()].successivo = p;
                spazio[spazio.getCoda()].precedente = spazio[p].precedente;
                spazio[p].precedente = spazio.getCoda();
                spazio[spazio[p].precedente].successivo= spazio.getCoda();
              }
             //Controllo se l'elemento che sto inserendo sostituirà la testa
              if(testa == p)
              {
                 testa = spazio.getCoda();  
                 //Setto i valori del nuovo elemento che sto inserendo in posizione p
                spazio[spazio.getCoda()].elemento = a;
                spazio[spazio.getCoda()].successivo = p;
                spazio[spazio.getCoda()].precedente = -1; 
                spazio[p].precedente = spazio.getCoda();       
              }
              //Caso in cui la lista è vuota e sto inserendo il primo elemento
              if(listavuota())
              {
                 testa = spazio.getCoda();
                 coda = testa;
                 spazio[spazio.getCoda()].successivo = -1;   
                 spazio[spazio.getCoda()].precedente = -1;
                 spazio[spazio.getCoda()].elemento = a;       
              }
              
              
              spazio.setCoda(NCodaSpazio);
              spazio[NCodaSpazio].successivo = -1;
        
          }
          else
          {
             cout << "Errore: Non c'e' spazio per inserire l'elemento" << endl;    
          }
        }
        else
        {
            cout << "Posizione non corretta" << endl;    
        }
    }
    
    void Lista::canclista(Lista::posizione p)
    { 
        /*Precondizione = La posizione passata non deve essere maggiore del
        numero massimo di elementi del vettore spazio*/
       if((p >= 0) && (p < N))
       {
          //debug
          //cout << "Testa: " << testa << " Coda: " << coda << " Posizione: " << p << endl;
          //Cancellamento dell'elemento dalla lista*************************************
          //sto cancellando un elemento centrale
          if((p != testa) && (p != coda))
          {
             spazio[spazio[p].precedente].successivo = spazio[p].successivo;
             spazio[spazio[p].successivo].precedente = spazio[p].precedente;
             //debug
             //cout << "Cancello un elemento centrale" << endl;
          }
          //sto cancellando la testa
          if((p == testa) && (p != coda))
          {
              spazio[spazio[p].successivo].precedente = -1;
              testa =  spazio[p].successivo;
              //debug
             //cout << "Cancello la testa" << endl;
          }
          //sto cancellando la coda
          if((p != testa) && (p == coda))
          {
              spazio[spazio[p].precedente].successivo = -1;
              coda = spazio[p].precedente;
              //debug
             //cout << "Cancello la coda" << endl;
          }
          //la lista è di un solo elemento
          if((p == testa) && (p == coda))
          {
              testa = -1;
              coda = -1;
              
          }
          int temp = spazio.getCoda();
          //Accodamento della cella eliminata alla lista Spazio*************************
          //caso in cui la lista spazio era vuota
          if(temp == -1)
          {
             //debug
             //cout << "La lista SPAZIO era vuota" << endl; 
             spazio.setTesta(p);
             spazio.setCoda(p);
             spazio[p].precedente = -1;
             spazio[p].successivo = -1;
             spazio[p].elemento = 0;
          }
          else //tutti gli altri casi
          {
              spazio[temp].successivo = p;
              spazio[p].precedente = temp;
              spazio[p].successivo = -1;
              spazio[p].elemento = 0;
              spazio.setCoda(p);
          }
        }
        else
        {
            cout << "Posizione non corretta" << endl;    
        }
    }
    Il file main.cpp:
    codice:
    #include <cstdlib>
    #include <iostream>
    #include "listap.h"
    using namespace std;
    
    int main(int argc, char *argv[])
    {
        Lista l1;
        int i, pos;
        for(i = 0; i < 104; i++)
        {
        pos = l1.primoLista();
        l1.inslista(i,pos);
        pos = l1.primoLista();
        cout << " " << l1.leggilista(pos) << " " << pos << endl;
        }
        
        l1.canclista(4);
        cout << " X" << l1.leggilista(4) << " " << pos << endl;
        l1.inslista(666,5);
        cout << l1.leggilista(l1.preclista(5));
        cout << l1.leggilista(l1.succlista(3));
        cout << l1.listavuota();
        for(i = 0; i < 100; i++)
        {
           l1.canclista(i);
        }
        cout << l1.listavuota();
        cout << "FINELISTA:" << l1.finelista(i-1);
        l1.canclista(3);
        system("PAUSE");
        return EXIT_SUCCESS;
    }

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se non vuoi fornire un'implementazione alle funzioni virtuali le devi dichiarare virtuali pure.
    Es:
    virtual void crealista()=0;
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    32
    Ok perfetto ora il codice funziona
    Grazie mille per l'aiuto

    se non mi aiutavi dovevo ancora stare qui a per colpa del prof che si dimentica di dire che alla fine della dichiarazione del metodo virtuale si mette =0;

  4. #4
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    32
    scusami ancora ma sta accadendo al codice qualcosa di strano : ho aggiunto il =0 prima alla fine dei metodi virtual ma a quei metodi virtuali dove alla fine c'è la parola const mi appare il seguente errore:

    expected `;' before "const"

    come mai?? il bello è che prima funzionavano, poi facendo qualche test non funziona più.. se è incollo il nuovo codice per far vedere le modifiche apportate.

  5. #5
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,304

    Moderazione

    Prendi visione del Regolamento interno: il linguaggio va obbligatoriamente indicato nel titolo ed il codice va postato indentato e all'interno degli appositi tag CODE.

    Questa discussione la sistemo io.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    =0 dev'essere l'ultimo token prima del ;

    codice:
    virtual bool listavuota() const =0;
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Utente di HTML.it
    Registrato dal
    Nov 2010
    Messaggi
    32
    ok ora funziona tutto perfettamente
    Grazie mille perla disponibilità

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 © 2024 vBulletin Solutions, Inc. All rights reserved.