PROBLEMA Problema vettore a puntatore a classe base [C++]

Mr.Cobra

Nuovo Utente
Il programma che devo fare è un programma in cui ho due classi una base Utente e una derivata Uposta. La prima ha gli elementi codice fiscale cognome di tipo stringa di tipo char allocata dinamicamente e un elemento oggetto di tipo data. La seconda eredita gli elementi della prima e in più aggiunge un elemento indirizzo sempre una stringa char allocata dinamicamente. Entrambe devono avere una funzione virtuale di controllo virtuale, che nella prima stabilisce se il codice fiscale sia valido, mentre nella seconda mi stabilisce se l'indirizzo email sia valido e quindi se ci sia una e una sola @ all'interno della stringa. Devo creare in fine un vettore in cui inserisco gli oggetti, ma ho un problema in quest'ultimo punto. Ho creato un vettore di elementi di tipo puntatore a classe base, cioè utente, ma quando devo attivare nella funzione immetti una funzione non virtuale esclusiva della funzione Derivata ho problemi. Ho pensato ad una soluzione cioè trasformare quella funzione, esclusiva della funzione derivata in una virtuale, ma vorrei una soluzione più elegante senza usare nessun tipo cast avete suggerimenti?

Qui è dove ho il problema:

Vettlib.h:

C++:
#ifndef VETTLIB_H
#define VETTLIB_H

#include "Upostalib.h"

#include <fstream>

namespace Email{
    
    typedef Utente *pntUtente;
    
    class Vettore{
        
        private:
            static const int N=20;
            pntUtente Vett[N];
            int Count;
        
        public:
            Vettore(){ for(int i=0; i<N; i++) Vett[i]=0; };
            
            bool Empty()const {return Count==0; };
            bool Full()const {return Count==N; };
            
            int Immetti(const pntUtente &)throw(Errore);
            pntUtente Estrai(const int &);
            
            void Stampa_video()const;
            void Stampa_file(const char *)const throw(const string);
            
            
    };
    
}

#endif
Vettfun.cpp:

C++:
#include "Vettlib.h"

namespace Email{
    
    int Vettore::Immetti(const pntUtente &V)throw(Errore){
        if(V->Check()==1){
            throw(V->get_CodFiscale());
        }else if(V->Check()==2){
            throw(V->get_Indirizzo());
        }else if(V->Check()==0){
            Vett[Count]=V;
            Count++;
            return Count-1;
        }
    }
        
    

    pntUtente Vettore::Estrai(const int &P){
        if(Count>=P){
            pntUtente temp=Vett[P];
            for(int i=0; i<Count; i++){
                Vett[i]=Vett[i+1];
            }
            Count--;
            return temp;
        }
    }
            
    void Vettore::Stampa_video()const{
        for(int i=0; i<Count; i++){
            cout<<i<<") "<<*Vett[i]<<endl;
        }
    }
    
    void Vettore::Stampa_file(const char *Nome)const throw(const string){
        fstream File;
        File.open(Nome);
        if(!File){
            throw("\n Errore durante l'apertura del file \n");
        }
        for(int i=0; i<N; i++){
            if(Vett[i]){
                File<<*Vett[i]<<endl;
            }
        }
        File.close();
    }
    
    
    
}
Questo è l'errore che mi da:

Immagine7.png


Questo è tutto il programma se vi interessa:

Datalib.h:

C++:
#ifndef DATALIB_H
#define DATALIB_H

#include <iomanip>
#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

namespace Email{
    
    class Data{
        
        friend ostream &operator<<(ostream &, const Data &);
        friend istream &operator>>(istream &, Data &);
        
        private:
            int Giorno;
            int Mese;
            int Anno;
        
        protected:
        virtual ostream &stampa(ostream &)const;
        virtual istream &leggi(istream &);
        
        public:
            Data(const int G=0, const int M=0, const int A=0):Giorno(G), Mese(M), Anno(A){ };
            Data(const Data &D):Giorno(D.Giorno), Mese(D.Mese), Anno(D.Anno){ };
            
            void set_Data(const Data &D){set_Giorno(D.Giorno); set_Mese(D. Mese); set_Anno(D.Anno);};
            void set_Giorno(const int G){ Giorno=G; };
            void set_Mese(const int M){ Mese=M; };
            void set_Anno(const int A){ Anno=A; };
            
            const int get_Giorno(){ return Giorno; };
            const int get_Mese(){ return Mese; };
            const int get_Anno(){ return Anno;};
            
            const Data &operator=(const Data &);
            bool operator==(const Data &)const;
            bool operator!=(const Data &)const;
        
    };
    
}
#endif
Datafun.cpp

C++:
#include "Datalib.h"

namespace Email{
    
    ostream &operator<<(ostream &out, const Data &D){
        D.stampa(out);
        return out;
    }
    
    istream &operator>>(istream &in, Data &D){
        D.leggi(in);
        return in;
    }
    
    ostream &Data::stampa(ostream &out)const{
        out<<"\n | Giorno: "<<Giorno<<"| Mese: "<<Mese<<"| Anno: "<<Anno<<endl;
        return out;
    }   
    
    istream &Data::leggi(istream &in){
        cout<<"\n Inserisci il giorno: ";
        in>>Giorno;
        cout<<"\n Inserisci il mese: ";
        in>>Mese;
        cout<<"\n Inserisci l'anno': ";
        in>>Anno;
        return in;
    }
        
    const Data &Data::operator=(const Data &D){
        if(&D!=this) set_Data(D);
    }

    bool Data::operator==(const Data &D)const{
        return (Giorno==D.Giorno&& Mese==D.Mese&& Anno==D.Anno);
    }

    bool Data::operator!=(const Data &D)const{
        return (!this->operator==(D));
    }
        
}
Utentelib.h

C++:
#ifndef UTENTELIB_H
#define UTENTELIB_H

#include "Datalib.h"
#include "Errorelib.h"

#define DIM 100

namespace Email{
    
    typedef char Buffer [DIM];
    
    class Utente{
        
        friend ostream &operator<<(ostream &, const Utente &);
        friend istream &operator>>(istream &, Utente &);
        
        private:
            char *CodFiscale;
            char *Cognome;
            Data DaRegistrazione;
            bool ContrCF(const char *)const;
        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);
        
        public:
            Utente(const char * ="", const char * ="", const int =0, const int =0, const int =0);
            Utente(const Utente &);
            ~Utente(){ delete [] CodFiscale; delete [] Cognome; };
            
            void set_Utente(const Utente &);
            void set_CodFiscale(const char *);
            void set_Cognome(const char *);
            
            const char *get_CodFiscale(){ return CodFiscale; };
            const char *get_Cognome(){ return Cognome; };
            
            const Utente &operator=(const Utente &);
            bool operator==(const Utente &)const;
            bool operator!=(const Utente &)const;
            virtual int Check()const;   
    };
    
}

#endif
Utentefun.cpp

C++:
#include "Utentelib.h"


namespace Email{
    
    Utente::Utente(const char *CF, const char *CO, const int G, const int M, const int A):CodFiscale(new char [strlen (CF)+1]), Cognome(new char [strlen(CO)+1]), DaRegistrazione(G, M, A){
        strcpy(CodFiscale, CF);
        strcpy(Cognome, CO);
    }
    
    Utente::Utente(const Utente &U):CodFiscale(new char [strlen (U.CodFiscale)+1]), Cognome(new char [strlen(U.Cognome)+1]), DaRegistrazione(U.DaRegistrazione){
        strcpy(CodFiscale, U.CodFiscale);
        strcpy(Cognome, U.Cognome);   
    }       

    void Utente::set_Utente(const Utente &U){
        set_CodFiscale(U.CodFiscale);
        set_Cognome(U.Cognome);
    }
    
    void Utente::set_CodFiscale(const char *CF){
        if(CodFiscale) delete[] CodFiscale;
        CodFiscale=new char [strlen (CF)+1];
        strcpy(CodFiscale, CF);
    }
    void Utente::set_Cognome(const char *CO){
        if(Cognome) delete[] Cognome;
        Cognome=new char [strlen (CO)+1];
        strcpy(Cognome, CO);
    }
    
    istream &operator>>(istream &in, Utente &U){
        return U.leggi(in);     
    }
    
    ostream &operator<<(ostream &out, const Utente &U){
        return U.stampa(out);     
    }
    
    ostream &Utente::stampa(ostream &out)const{
        out<<"\n | Codice Fiscale: "<<CodFiscale<<"| Cognome: "<<Cognome<<"| Data di registrazione: "<<DaRegistrazione;
        return out;
    }   
    
    istream &Utente::leggi(istream &in){
        Buffer b;
        cout<<"\n Inserisci il codice fiscale: ";
        in.getline(b, DIM-1, '\n');
        set_CodFiscale(b);
        in.ignore();
        cout<<"\n Inserisci il cognome: ";
        in.getline(b,DIM-1, '\n');
        set_Cognome(b);   
        in.ignore();
        in>>DaRegistrazione;
        return in;
    }

    const Utente &Utente::operator=(const Utente &U){
        if(&U!=this) set_Utente(U);
    }
    
    bool Utente::operator==(const Utente &U)const{
        return (!strcmp(CodFiscale, U.CodFiscale) && !strcmp(CodFiscale, U.CodFiscale) && DaRegistrazione.operator==(U.DaRegistrazione));
    }
    
    bool Utente::operator!=(const Utente &U)const{
        return (!this->operator==(U));
    }
    
    int Utente::Check()const{
        if(!ContrCF(CodFiscale)){
            throw ("\n Codice fiscale non valido");
            return 1;
        }else return 0;
    }
    
    bool Utente::ContrCF(const char *CF)const{
        char minN='0';
        char maxN='9';
        char minA='A';
        char maxA='Z';
        int countN=0;
        int countA=0;
        if(strlen(CF)==16){
            for(int i=0; i<16; i++){
                if(CF[i]>=minN && CF[i]<=maxN){
                    countN++;
                }
                if(CF[i]>=minA && CF[i]<=maxA){
                    countA++;
                }
            }
            if(countN>0 && countA>0){
                return true;
            }else return false;
        }
    }
}
Upostalib.h

C++:
#ifndef UPOSTALIB_H
#define UPOSTALIB_H

#include "Utentelib.h"

namespace Email{
    
    class Uposta: public Utente{
        
        friend ostream &operator<<(ostream &, const Uposta &);
        friend istream &operator>>(istream &, Uposta &);
        
        private:
            char *Indirizzo;
        
        protected:
        virtual ostream &stampa(ostream &)const;
        virtual istream &leggi(istream &);
        bool ContrI(const char *)const;
        
        public:
            Uposta(const char * ="", const char * ="", const int =0, const int =0, const int =0, const char * ="");
            Uposta(const Uposta &);
            ~Uposta(){ delete [] Indirizzo; };
            
            void set_Indirizzo(const char *);
            void set_Uposta(const Uposta &);
            
            const char *get_Indirizzo(){ return Indirizzo; };
            
            const Uposta &operator=(const Uposta &);
            bool operator==(const Uposta &)const;
            bool operator!=(const Uposta &)const;
            
            virtual int Check()const;   
        
    };
    
}

#endif
Upostafun.cpp

C++:
#include "Upostalib.h"


namespace Email{
    
    Uposta::Uposta(const char *CF, const char *CO, const int G, const int M, const int A, const char *I):Utente(CF, CO, G, M, A), Indirizzo(new char [strlen(I)+1]) {
        strcpy(Indirizzo, I);
    }
    
    Uposta::Uposta(const Uposta &UP):Utente(UP), Indirizzo(new char [strlen(UP.Indirizzo)+1]){
        strcpy(Indirizzo, UP.Indirizzo);
    }       
    
    void Uposta::set_Indirizzo(const char *I){
        if(Indirizzo) delete[] Indirizzo;
        Indirizzo=new char [strlen (I)+1];
        strcpy(Indirizzo, I);
    }
    
    void Uposta::set_Uposta(const Uposta &UP){
        Utente::set_Utente(UP);
        set_Indirizzo(UP.Indirizzo);
    }
    
    istream &operator>>(istream &in, Uposta &UP){
        return UP.leggi(in);     
    }
    
    ostream &operator<<(ostream &out, const Uposta &UP){
        return UP.stampa(out);     
    }
    
    ostream &Uposta::stampa(ostream &out)const{
        Utente::stampa(out);
        out<<" | Indirizzo: "<<Indirizzo<<endl;
        return out;
    }   
    
    istream &Uposta::leggi(istream &in){
        Utente::leggi(in);
        Buffer b;
        cout<<"\n Inserisci l'indirizzo': ";
        in.getline(b, DIM-1, '\n');
        set_Indirizzo(b);
        in.ignore();
        return in;
    }

    const Uposta &Uposta::operator=(const Uposta &UP){
        if(&UP!=this)set_Uposta(UP);
    }
    
    bool Uposta::operator==(const Uposta &UP)const{
        return (!strcmp(Indirizzo, UP.Indirizzo) && Utente::operator==(UP));
    }
    
    bool Uposta::operator!=(const Uposta &UP)const{
        return (!this->operator==(UP));
    }
    
    int Uposta::Check()const{
        if(!ContrI(Indirizzo)){
            throw("\n Indirizzo di posta elettronica errato!");
            return 2;
        }else return 0;
    }
        
    bool Uposta::ContrI(const char *I)const{
        char simb='@';
        int count=0;
        int dim=0;
        dim=strlen(I);
        for(int i=0; i<dim; i++){
            if(I[i]==simb){
                count++;
            }
        }
        if(count==1){
            return true;
        }else return false;
        
    }
    
}
Errorelib.h

C++:
#ifndef ERRORELIB_H
#define ERRORELIB_H

#include <string>

using namespace std;

namespace Email{
    
    class Errore{
        
        private:
            string error;
        
        public:
            const char *what()const;
        
    };
    
}

#endif
Errorefun.h

C++:
#include "Errorelib.h"

namespace Email{
    
    const char *Errore::what()const{
        string msg;
        msg= "\n Errore durante l'inserimento! "+error;
        return msg.c_str();
    }
    
}
 

Entra

oppure Accedi utilizzando