RISOLTO [C++] Il programma non mi da nessun errore ma si interrompe e non accetta comandi

Stato
Discussione chiusa ad ulteriori risposte.

Mr.Cobra

Nuovo Utente
69
1
Bruttpitt ti diceva giustamente che stavi copiando dati nel buffer, che è una stringa che non avevi allocato.
Ti basta dichiarare buffer come char [DIM] ed averlo quindi allocato sullo stack. Poi la funzione Copia prende l’indirizzo della memoria che punta buffer e l’indirizzo di una stringa per poterla allocare.

Ci sono alternative, come allocare direttamente le stringhe nel main e fregarsene se del spazio non viene sfruttato. Questa evita l’uso di puntatore a puntatore.

Il codice puoi scrivertelo da solo, ora che sai semplicemente che devi cambiare il tipo dell’argomento da char * a char* &
Quindi vedi se ho capito e vedi se così va bene.
Al posto di usare il typedef char* buffer [DIM] che ho dichiarato il veicololib.h , dichiaro buffer come variabile automatica locale all'interno della funzione Copia nel modulo Supportofun.cpp e così viene allocata nell'area stack della memoria. E quindi devo dichiaralo solo così giusto?char *buffer [DIM]; .
Quindi Copia diventerà void Copia(char *&) ? E quindi nel main gli passo solo s1?
 

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Quindi vedi se ho capito e vedi se così va bene.
Al posto di usare il typedef char* buffer [DIM] che ho dichiarato il veicololib.h , dichiaro buffer come variabile automatica locale all'interno della funzione Copia nel modulo Supportofun.cpp e così viene allocata nell'area stack della memoria. E quindi devo dichiaralo solo così giusto?char *buffer [DIM]; .
Quindi Copia diventerà void Copia(char *&) ? E quindi nel main gli passo solo s1?
Beh, è una altra soluzione.
Però non va bene il tipo. char *nome [dim] è un array di puntatori; a te serve un array normalissimo che è char nome[dim].
Ti conviene studiare bene il capitolo sui puntatori e array, scrivendo del codice magari.
 
Ultima modifica:

BrutPitt

Utente Attivo
1,166
1,262
Invece di dichiarare un puntatore a puntatore, potrebbe semplicemente cambiare la funzione void Copia in Str Copia e restituire il valore dell'indirizzo di memoria allocato, via return s;
Funzione Copia che tra l'altro non vedo piu' chiamata dal main...

Comunque qualcosa del genere
C:
char *Copia(char *buffer)
{
        cin.getline(buffer, DIM-1, '\n');
        // delete [] s;  ... lo togliamo
        char *s=new char [strlen(buffer)+1];
        strcpy(s, buffer);
        //   buffer[]=nullptr;  ASSOLUTAMENTE NO!
        cin.ignore();
       return s;
}

// nel Main, o dove chiami Copia

     Str s1 = Copia(buffer); // dove buffer e' char buffer[DIM];
// ora fai le tue cose con s1
...
// quando non ti serve piu', prima che esca dalla "visibilita' " locale chiami:
   delete [] s1;

L'allocazione del buffer e' corretta come dice Achille: char buffer [DIM];
Quello rimane fisso e allocato per tutta l'esecuzione del programma... non lo devi deallocare (perche' dichiarato "staticamente")
Quindi toigli quel buffer[] = nullptr; da Copia

Se mi date un minuto mi rileggo le modifiche che avete fatto... perche' ho risposto al volo... e magari hoi scritto delle castronerie ;)
Post unito automaticamente:

Se il tuo dubbio e' quello di "pulire" buffer ... non serve: il contenuto viene sovrascritto ad ogni getline.
Quindi, se lo usi solo per prendere i dati con getline, e copiarli in un altro "contenitore" ... lo puoi lasciare cosi' com'e'.

EDIT:
Pero' guardavo adesso che s1 ed s2 finiscono in Automobile... quindi non puoi deallocare s1 ed s2 se li utilizzi altrove, senza copiarli
Adesso mi vado a cercare Auotomobile...
riEDIT:
... che non mi pare ci sia... in questo codice.
Comunque hai 2 alternative in Automobile
1)
copiare ancora una volta i 2 buffers (strcpy), in altrettanti buffers nuovamente allocati in Automobile, cosi' puoi deallocare s1 ed s2 dal main (soluzione meno elegante)
2) Passare, come fai attualmente, gli indirizzi... e gestire la funzione di deallocazione nel distruttore di Automobile
 
Ultima modifica:

Mr.Cobra

Nuovo Utente
69
1
Beh, è una altra soluzione.
Però non va bene il tipo. char *nome [dim] è un array di puntatori; a te serve un array normalissimo che è char nome[dim].
Ti conviene studiare bene il capitolo sui puntatori e array, scrivendo del codice magari.

Si me ne sono accorto ho scritto una castroneria esagerata abituato ad allocare tutto dinamicamente metto puntatori anche dove non servono :asd:

Invece di dichiarare un puntatore a puntatore, potrebbe semplicemente cambiare la funzione void Copia in Str Copia e restituire il valore dell'indirizzo di memoria allocato, via return s;
Funzione Copia che tra l'altro non vedo piu' chiamata dal main...

Comunque qualcosa del genere
C:
char *Copia(char *buffer)
{
        cin.getline(buffer, DIM-1, '\n');
        // delete [] s;  ... lo togliamo
        char *s=new char [strlen(buffer)+1];
        strcpy(s, buffer);
        //   buffer[]=nullptr;  ASSOLUTAMENTE NO!
        cin.ignore();
       return s;
}

// nel Main, o dove chiami Copia

     Str s1 = Copia(buffer); // dove buffer e' char buffer[DIM];
// ora fai le tue cose con s1
...
// quando non ti serve piu', prima che esca dalla "visibilita' " locale chiami:
   delete [] s1;

L'allocazione del buffer e' corretta come dice Achille: char buffer [DIM];
Quello rimane fisso e allocato per tutta l'esecuzione del programma... non lo devi deallocare (perche' dichiarato "staticamente")
Quindi toigli quel buffer[] = nullptr; da Copia

Se mi date un minuto mi rileggo le modifiche che avete fatto... perche' ho risposto al volo... e magari hoi scritto delle castronerie ;)
Post unito automaticamente:

Se il tuo dubbio e' quello di "pulire" buffer ... non serve: il contenuto viene sovrascritto ad ogni getline.
Quindi, se lo usi solo per prendere i dati con getline, e copiarli in un altro "contenitore" ... lo puoi lasciare cosi' com'e'.

EDIT:
Pero' guardavo adesso che s1 ed s2 finiscono in Automobile... quindi non puoi deallocare s1 ed s2 se li utilizzi altrove, senza copiarli
Adesso mi vado a cercare Auotomobile...
riEDIT:
... che non mi pare ci sia... in questo codice.
Comunque hai 2 alternative in Automobile
1)
copiare ancora una volta i 2 buffers (strcpy), in altrettanti buffers nuovamente allocati in Automobile, cosi' puoi deallocare s1 ed s2 dal main (soluzione meno elegante)
2) Passare, come fai attualmente, gli indirizzi... e gestire la funzione di deallocazione nel distruttore di Automobile

Ho capito semmai ora ti posto tutto il programma, cambiando solo Copia, secondo i consigli che mi avete dato, così mi puoi vedere qual'è l'alternativa migliore o se ti viene in mente qualcos'altro. Se hai qualche altro consiglio su qualche altra parte del programma mi farebbe molto piacere.
Generalmente non lo posto tutto perché capisco che possa annoiare leggersi un intero programma.
Come ho detto anche ad achille vorrei continuare dopo l'esame a studiare C++ se hai qualche consiglio e link utile da passarmi mi faresti un piacere. Ma anche linguaggi che sono simili a C++ che possono essere utili.

Veicololib.h

C++:
#ifndef VEICOLOLIB_H
#define VEICOLOLIB_H

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

#define DIM 100

using namespace std;

namespace Parcheggio{

    typedef char buffer [DIM];

    class Veicolo{

        friend ostream &operator<<(ostream &, const Veicolo &);
        friend istream &operator>>(istream &, Veicolo &);


        private:
            char *Nometipo;
            char *Marca;

        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);

        public:
            Veicolo(const char * ="", const char * ="");
            Veicolo(const Veicolo &);
            ~Veicolo();
    
            void set_Veicolo(const Veicolo &);
            void set_Nometipo(const char *);
            void set_Marca(const char *);

            const char * get_Nometipo() { return Nometipo; };
            const char * get_Marca() { return Marca; };

            const Veicolo &operator=(const Veicolo &);
            bool operator==(const Veicolo &)const;
            bool operator!=(const Veicolo &)const;

    };

}
#endif

Veicolofun.cpp

C++:
#include "Veicololib.h"

namespace Parcheggio{

    Veicolo::Veicolo(const char *N, const char *M): Nometipo(new char [strlen(N)+1]), Marca(new char [strlen(M)+1]){
        strcpy(Nometipo, N);
        strcpy(Marca, M);
    }

    Veicolo::Veicolo(const Veicolo &V) : Nometipo(new char [strlen(V.Nometipo)+1]), Marca(new char [strlen(V.Marca)+1]){
        strcpy(Nometipo, V.Nometipo);
        strcpy(Marca, V.Marca);
    }

    void Veicolo::set_Veicolo(const Veicolo &V){
        set_Nometipo(V.Nometipo);
        set_Marca(V.Marca);
    }

    void Veicolo::set_Nometipo(const char *N){
        delete[] Nometipo;
        Nometipo= new char [strlen(N)+1];
        strcpy(Nometipo, N);
    }

    void Veicolo::set_Marca(const char *M){
        delete[] Marca;
        Marca= new char [strlen(M)+1];
        strcpy(Marca, M);
    }

    Veicolo::~Veicolo(){
        delete Nometipo;
        delete Marca;
    }

    const Veicolo &Veicolo::operator=(const Veicolo & V){
        if(&V != this){
            if(Nometipo) delete [] Nometipo;
            if(Marca) delete [] Marca;
            set_Veicolo(V);
        }
        return *this;
    }

    bool Veicolo::operator==(const Veicolo &V)const {
        return (!strcmp(Nometipo, V.Nometipo) && !strcmp(Marca, V.Marca));
    }

    bool Veicolo::operator!=(const Veicolo &V)const{
        return (!this->operator==(V));
    }

    ostream &operator<<(ostream &out, const Veicolo &V){
        return V.stampa(out);
    }

    istream &operator>>(istream &in, Veicolo &V){
        return V.leggi(in);
    }

    ostream &Veicolo::stampa(ostream &out)const{
        out<<"| Nome del tipo di veicolo: "<<Nometipo<<"| Marca: "<<Marca;
        return out;
    }

    istream &Veicolo::leggi(istream &in){
        buffer b;
        cout<<"Inserisci il nome del tipo di veicolo: ";
        in.getline(b, DIM-1, '\n');
        set_Nometipo(b);
        in.ignore();
        cout<<"Inserisci la marca del veicolo: ";
        in.getline(b, DIM-1,'\n');
        set_Marca(b);
        in.ignore();
        return in;
    }

}

Automobilelib.h

C++:
#ifndef AUTOMOBILELIB_H
#define AUTOMOBILELIB_H

#include "Veicololib.h"

namespace Parcheggio{

    class Automobile: public Veicolo{

        friend ostream &operator<<(ostream &,const Automobile &);
        friend istream &operator>>(istream &, Automobile &);

        private:
            char *Alimentazione;

        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);

        public:
            Automobile(const char * ="", const char * ="", const char * ="");
            Automobile(const Automobile &);
            ~Automobile(){ delete [] Alimentazione;};

            void set_Alimentazione(const char*);
            const char * get_Alimentazione(){ return Alimentazione; };

            const Automobile &operator=(const Automobile &);
            bool operator==(const Automobile &)const;
            bool operator!=(const Automobile &)const;

    };

}
#endif

Automobilefun.cpp

C++:
#include "Automobilelib.h"

namespace Parcheggio{

    Automobile::Automobile(const char *N, const char * M, const char *A) : Veicolo(N, M), Alimentazione(new char [strlen(A)+1]){
        strcpy(Alimentazione, A);
    }

    Automobile::Automobile(const Automobile & A) : Veicolo(A), Alimentazione(new char [strlen (A.Alimentazione)+1]){
        strcpy(Alimentazione, A.Alimentazione);
    }

    void Automobile::set_Alimentazione(const char *A){
        delete [] Alimentazione;
        Alimentazione= new char [strlen(A)+1];
        strcpy(Alimentazione, A);
    }

    const Automobile &Automobile::operator=(const Automobile &A){
        if(&A!=this){
            Veicolo::operator=(A);
            if(Alimentazione) delete [] Alimentazione;
            set_Alimentazione(A.Alimentazione);
        }
    }

    bool Automobile::operator==(const Automobile &A)const{
        return (Veicolo::operator==(A) && !strcmp(Alimentazione, A.Alimentazione));
    }

    bool Automobile::operator!=(const Automobile &A)const{
        return ( !this->operator==(A));
    }

    ostream &operator<<(ostream &out, const Automobile &A){
        return A.stampa(out);
    }

    istream &operator>>(istream &in, Automobile &A){
        return A.leggi(in);
    }

    ostream &Automobile::stampa(ostream &out)const{
        Veicolo::stampa(out);
        out<<"| Alimentazione: "<<Alimentazione<<endl;
        return out;
    }

    istream &Automobile::leggi(istream &in){
        buffer b;
        Veicolo::leggi(in);
        in.getline(b, DIM-1, '\n');
        set_Alimentazione(b);
        in.ignore();
        return in;
    }

}

Motolib.h

C++:
#ifndef MOTOLIB_H
#define MOTOLIB_H

#include "Veicololib.h"

namespace Parcheggio{

    class Moto: public Veicolo{

        friend ostream &operator<<(ostream &,const Moto &);
        friend istream &operator>>(istream &, Moto &);
        
        private:
            char *Tipo;

        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);

        public:
            Moto(const char * ="", const char * ="", const char * ="");
            Moto(const Moto &);
            ~Moto(){ delete [] Tipo; };
    
            void set_Tipo(const char *);
            const char * get_Tipo() { return Tipo; };
    
            const Moto &operator=(const Moto &);
            bool operator==(const Moto &);
            bool operator!=(const Moto &);
    
    };

}
#endif

Motofun.cpp

C++:
#include "Motolib.h"

namespace Parcheggio{

    Moto::Moto(const char *N, const char *M, const char *T) : Veicolo(N,M), Tipo(new char [strlen(T)+1]){
        strcpy(Tipo,T);
    }

    Moto::Moto(const Moto &M) : Veicolo(M), Tipo(new char [strlen(M.Tipo)+1]){
        strcpy(Tipo,M.Tipo);
    }

    void Moto::set_Tipo(const char *T){
        delete [] Tipo;
        Tipo=new char [strlen(T)+1];
        strcpy(Tipo,T);
    }

    const Moto &Moto::operator=(const Moto &M){
        if(&M!=this){
            Veicolo::operator=(M);
            if(Tipo) delete [] Tipo;
            set_Tipo(M.Tipo);
        }
    }

    bool Moto::operator==(const Moto &M){
        return (Veicolo::operator==(M) && strcmp(Tipo, M.Tipo));
    }

    bool Moto::operator!=(const Moto &M){
        return (! this->operator==(M));
    }

    ostream &operator<<(ostream &out, const Moto &M){
        return M.stampa(out);
    }

    istream &operator>>(istream &in, Moto &M){
        return M.leggi(in);
    }

    ostream &Moto::stampa(ostream &out)const {
        Veicolo::stampa(out);
        out<<"| Tipo: "<<Tipo;
        return out;
    }


    istream &Moto::leggi(istream &in){
        buffer b;
        Veicolo::leggi(in);
        in.getline(b, DIM-1, '\n');
        set_Tipo(b);
        in.ignore();
        return in;
    }

}

Garagelib.h

C++:
#ifndef GARAGELIB_H
#define GARAGELIB_H

#include "Veicololib.h"
#include "Automobilelib.h"
#include "Motolib.h"
#include "Errorelib.h"
#include <fstream>

namespace Parcheggio{
    typedef Veicolo *pntVeicolo;
    class Garage{

        private:
            static const int N=20;
            pntVeicolo Vett[N];
            static int Count;

        public:
            Garage(){for(int i=0; i<N; i++) Vett[i]=0; };
    
            bool Empty() const {return Count==0;};
            bool Full() const {return Count==N;};
    
            int Immetti(Veicolo *)throw(Errore);
            pntVeicolo Estrai(const int &);
    
            void Stampa_Video()const;
            void Stampa_File(const char *)const throw(const char *);
    

    };

}
#endif

Garagefun.c

C++:
#include "Garagelib.h"

namespace Parcheggio{

    int Garage::Count=0;

    int Garage::Immetti(Veicolo *V) throw(Errore){
        int i;
        if(strcmp(V->get_Nometipo(), "Automobile") && strcmp(V->get_Nometipo(), "Motocicletta")){
            throw(Errore(V->get_Nometipo()));
        }
        Vett[Count]=V;
        Count++;
        return Count-1;
    }

    pntVeicolo Garage::Estrai(const int &P){
        if(Count>=P){
            pntVeicolo temp= Vett[P];
            for(int i=P; i<Count; i++){
                Vett[i]=Vett[i+1];
            }
            Count--;
            return temp;
        }
    }

    void Garage::Stampa_Video()const{
        for(int i=0; i<Count; i++ ){
            cout<<i<<") "<<*Vett[i]<<endl;
        }
    }

    void Garage::Stampa_File(const char *Nome)const throw(const char *){
        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();
    }

}

Errorelib.h

C++:
#ifndef ERRORELIB_H
#define ERRORELIB_H

#include <string>

using namespace std;
namespace Parcheggio{

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

}

#endif

Errorefun.cpp

C++:
#include "Errorelib.h"

namespace Parcheggio{

const char *Errore::what() const {
    string msg;
    msg = "\n Errore! Il veicolo inserito non è valido: " + error;
    return msg.c_str();
}

}

Supportolib.h

C++:
#ifndef SUPPORTOLIB_H
#define SUPPORTOLIB_H

#include "Veicololib.h"

namespace Parcheggio{

    typedef char *Str;
    void Stampa_Menu();
    char *Copia(char *);
}
#endif

Supportofun.cpp

C++:
#include "Supportolib.h"

namespace Parcheggio{

    void Stampa_Menu(){
        cout<<"/***Benvenuti all'interno del garage**/\n\n";
        cout<<"[0] Uscita \n";
        cout<<"[1] Insersci un veicolo nel garage \n";
        cout<<"[2] Estrai un veicolo dal garage \n";
        cout<<"[3] Stampa a video la lista dei veicoli \n";
        cout<<"[4] Stampa su file la lista dei veicoli \n";
        cout<<"Premi il tasto per scegliere l'operazione da svolgere : ";
 
    }

    char *Copia(char *buffer){
        cin.getline(buffer, DIM-1, '\n');
        s=new char [strlen(buffer)+1];
        strcpy(s, buffer);
        cin.ignore();
    }
}

main.cpp

C++:
#include <iostream>
#include <cstdlib>
#include <fstream>

#include "Veicololib.h"
#include "Automobilelib.h"
#include "Motolib.h"
#include "Garagelib.h"
#include "Errorelib.h"
#include "Supportolib.h"

using namespace std;
using namespace Parcheggio;


int main(int argc, char** argv) {
    int opzione;
    Garage G;
    buffer b;
    do{
        system("cls");
        Stampa_Menu();
        cin>>opzione;
    
        switch(opzione){
    
            case(1):
                cout<<"\n Inserisci un Automobile o una Motocicletta [A/M] : ";
                char risp;
                cin>>risp;
                if(!G.Full()){
                    if(risp=='A'){
                        cin.ignore();
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        Str s1=Copia(b);
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        Str s2=Copia(b);
                        try{
                            G.Immetti(new Automobile("Automobile", s1, s2));\\ scusate l'ignoranza ma s1 e s2 si sono trasformati in dati dell'oggetto?
                            delete [] s1; \\quindi non potrei de allocarli cosi?
                            delete [] s2;
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }else if(risp=='M'){
                        cin.ignore();
                        cout<<"\n Inserisci la marca della Motocicletta: ";
                        Str s3=Copia(b);
                        cout<<"\n Inserisci il tipo di Motocilcetta: ";
                        Str s4=Copia(b);
                        try{
                            G.Immetti(new Moto("Motocicletta", s3, s4)); \\ scusate l'ignoranza ma s1 e s2 si sono trasformati in dati dell'oggetto?
                            delete [] s3; \\quindi non potrei de allocarli cosi?
                            delete [] s4;
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }
                }else{
                    cout<<"\n Il Garage è pieno \n";
                }
            break;
        
            case(2):
                cin.ignore();
                cout<<"\n Inserisci la posizione del veicolo da estrarre: ";
                if(!G.Empty()){
                    int pos;
                    cin>>pos;
                    cin.ignore();
                    cout<<"\n Il veicolo estratto è :";
                    cout<<endl<<G.Estrai(pos)<<endl;
                    cout<<"\n il garage adesso è composto dai seguenti veicoli: ";
                    G.Stampa_Video();
                }else{
                    cout<<"\n Il garage è vuoto \n ";
                }
            break;
        
            case(3):
                cout<<"\n Lista dei veicoli presenti nel garage: ";
                if(!G.Empty()){
                    G.Stampa_Video();
                }else cout<<"\n Il garage è vuoto \n ";
                break;
        
            case(4):
                cin.ignore();
                cout<<"\n Inserisci il Percorso del file: ";
                cin.getline(b, DIM-1, '\n');
                try{
                    G.Stampa_File(b);
                }catch(const char *b){
                    cout<<b<<endl;
                }
                break;
            
        }
        system("pause");
    }while(opzione!=0);
    return 0;
}
Post unito automaticamente:

Che ne pensate di quest'altra soluzione?
C++:
int main(int argc, char** argv) {
    int opzione;
    Garage G;
    buffer b;
   
    do{
        system("cls");
        Stampa_Menu();
        cin>>opzione;
       
        switch(opzione){
       
            case(1):
                cout<<"\n Inserisci un Automobile o una Motocicletta [A/M] : ";
                char risp;
                cin>>risp;
                if(!G.Full()){
                    if(risp=='A'){
                        cin.ignore();
                        Automobile Atemp;
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Marca(b);
                        cin.ignore();
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Alimentazione(b);
                        cin.ignore();                       
                        try{
                            G.Immetti(new Automobile("Automobile", Atemp.get_Marca(), Atemp.get_Alimentazione()));
                            Atemp.~Automobile();
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }else if(risp=='M'){
                        cin.ignore();
                        Moto Mtemp;
                        cout<<"\n Inserisci la marca della Motocicletta: ";
                        cin.getline(b, DIM-1, '\n');
                        Mtemp.set_Marca(b);
                        cin.ignore();
                        cout<<"\n Inserisci il tipo di Motocilcetta: ";
                        cin.getline(b, DIM-1, '\n');
                        Mtemp.set_Tipo(b);
                        cin.ignore();
                        try{
                            G.Immetti(new Moto("Motocicletta", Mtemp.get_Marca(), Mtemp.get_Marca()));
                            Mtemp.~Moto();
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }
                }else{
                    cout<<"\n Il Garage è pieno \n";
                }
            break;

Però mi si blocca qui:
Immagine 2.png
 
Ultima modifica:

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Si me ne sono accorto ho scritto una castroneria esagerata abituato ad allocare tutto dinamicamente metto puntatori anche dove non servono :asd:



Ho capito semmai ora ti posto tutto il programma, cambiando solo Copia, secondo i consigli che mi avete dato, così mi puoi vedere qual'è l'alternativa migliore o se ti viene in mente qualcos'altro. Se hai qualche altro consiglio su qualche altra parte del programma mi farebbe molto piacere.
Generalmente non lo posto tutto perché capisco che possa annoiare leggersi un intero programma.
Come ho detto anche ad achille vorrei continuare dopo l'esame a studiare C++ se hai qualche consiglio e link utile da passarmi mi faresti un piacere. Ma anche linguaggi che sono simili a C++ che possono essere utili.

Veicololib.h

C++:
#ifndef VEICOLOLIB_H
#define VEICOLOLIB_H

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

#define DIM 100

using namespace std;

namespace Parcheggio{

    typedef char buffer [DIM];

    class Veicolo{

        friend ostream &operator<<(ostream &, const Veicolo &);
        friend istream &operator>>(istream &, Veicolo &);


        private:
            char *Nometipo;
            char *Marca;

        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);

        public:
            Veicolo(const char * ="", const char * ="");
            Veicolo(const Veicolo &);
            ~Veicolo();
   
            void set_Veicolo(const Veicolo &);
            void set_Nometipo(const char *);
            void set_Marca(const char *);

            const char * get_Nometipo() { return Nometipo; };
            const char * get_Marca() { return Marca; };

            const Veicolo &operator=(const Veicolo &);
            bool operator==(const Veicolo &)const;
            bool operator!=(const Veicolo &)const;

    };

}
#endif

Veicolofun.cpp

C++:
#include "Veicololib.h"

namespace Parcheggio{

    Veicolo::Veicolo(const char *N, const char *M): Nometipo(new char [strlen(N)+1]), Marca(new char [strlen(M)+1]){
        strcpy(Nometipo, N);
        strcpy(Marca, M);
    }

    Veicolo::Veicolo(const Veicolo &V) : Nometipo(new char [strlen(V.Nometipo)+1]), Marca(new char [strlen(V.Marca)+1]){
        strcpy(Nometipo, V.Nometipo);
        strcpy(Marca, V.Marca);
    }

    void Veicolo::set_Veicolo(const Veicolo &V){
        set_Nometipo(V.Nometipo);
        set_Marca(V.Marca);
    }

    void Veicolo::set_Nometipo(const char *N){
        delete[] Nometipo;
        Nometipo= new char [strlen(N)+1];
        strcpy(Nometipo, N);
    }

    void Veicolo::set_Marca(const char *M){
        delete[] Marca;
        Marca= new char [strlen(M)+1];
        strcpy(Marca, M);
    }

    Veicolo::~Veicolo(){
        delete Nometipo;
        delete Marca;
    }

    const Veicolo &Veicolo::operator=(const Veicolo & V){
        if(&V != this){
            if(Nometipo) delete [] Nometipo;
            if(Marca) delete [] Marca;
            set_Veicolo(V);
        }
        return *this;
    }

    bool Veicolo::operator==(const Veicolo &V)const {
        return (!strcmp(Nometipo, V.Nometipo) && !strcmp(Marca, V.Marca));
    }

    bool Veicolo::operator!=(const Veicolo &V)const{
        return (!this->operator==(V));
    }

    ostream &operator<<(ostream &out, const Veicolo &V){
        return V.stampa(out);
    }

    istream &operator>>(istream &in, Veicolo &V){
        return V.leggi(in);
    }

    ostream &Veicolo::stampa(ostream &out)const{
        out<<"| Nome del tipo di veicolo: "<<Nometipo<<"| Marca: "<<Marca;
        return out;
    }

    istream &Veicolo::leggi(istream &in){
        buffer b;
        cout<<"Inserisci il nome del tipo di veicolo: ";
        in.getline(b, DIM-1, '\n');
        set_Nometipo(b);
        in.ignore();
        cout<<"Inserisci la marca del veicolo: ";
        in.getline(b, DIM-1,'\n');
        set_Marca(b);
        in.ignore();
        return in;
    }

}

Automobilelib.h

C++:
#ifndef AUTOMOBILELIB_H
#define AUTOMOBILELIB_H

#include "Veicololib.h"

namespace Parcheggio{

    class Automobile: public Veicolo{

        friend ostream &operator<<(ostream &,const Automobile &);
        friend istream &operator>>(istream &, Automobile &);

        private:
            char *Alimentazione;

        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);

        public:
            Automobile(const char * ="", const char * ="", const char * ="");
            Automobile(const Automobile &);
            ~Automobile(){ delete [] Alimentazione;};

            void set_Alimentazione(const char*);
            const char * get_Alimentazione(){ return Alimentazione; };

            const Automobile &operator=(const Automobile &);
            bool operator==(const Automobile &)const;
            bool operator!=(const Automobile &)const;

    };

}
#endif

Automobilefun.cpp

C++:
#include "Automobilelib.h"

namespace Parcheggio{

    Automobile::Automobile(const char *N, const char * M, const char *A) : Veicolo(N, M), Alimentazione(new char [strlen(A)+1]){
        strcpy(Alimentazione, A);
    }

    Automobile::Automobile(const Automobile & A) : Veicolo(A), Alimentazione(new char [strlen (A.Alimentazione)+1]){
        strcpy(Alimentazione, A.Alimentazione);
    }

    void Automobile::set_Alimentazione(const char *A){
        delete [] Alimentazione;
        Alimentazione= new char [strlen(A)+1];
        strcpy(Alimentazione, A);
    }

    const Automobile &Automobile::operator=(const Automobile &A){
        if(&A!=this){
            Veicolo::operator=(A);
            if(Alimentazione) delete [] Alimentazione;
            set_Alimentazione(A.Alimentazione);
        }
    }

    bool Automobile::operator==(const Automobile &A)const{
        return (Veicolo::operator==(A) && !strcmp(Alimentazione, A.Alimentazione));
    }

    bool Automobile::operator!=(const Automobile &A)const{
        return ( !this->operator==(A));
    }

    ostream &operator<<(ostream &out, const Automobile &A){
        return A.stampa(out);
    }

    istream &operator>>(istream &in, Automobile &A){
        return A.leggi(in);
    }

    ostream &Automobile::stampa(ostream &out)const{
        Veicolo::stampa(out);
        out<<"| Alimentazione: "<<Alimentazione<<endl;
        return out;
    }

    istream &Automobile::leggi(istream &in){
        buffer b;
        Veicolo::leggi(in);
        in.getline(b, DIM-1, '\n');
        set_Alimentazione(b);
        in.ignore();
        return in;
    }

}

Motolib.h

C++:
#ifndef MOTOLIB_H
#define MOTOLIB_H

#include "Veicololib.h"

namespace Parcheggio{

    class Moto: public Veicolo{

        friend ostream &operator<<(ostream &,const Moto &);
        friend istream &operator>>(istream &, Moto &);
       
        private:
            char *Tipo;

        protected:
            virtual ostream &stampa(ostream &)const;
            virtual istream &leggi(istream &);

        public:
            Moto(const char * ="", const char * ="", const char * ="");
            Moto(const Moto &);
            ~Moto(){ delete [] Tipo; };
   
            void set_Tipo(const char *);
            const char * get_Tipo() { return Tipo; };
   
            const Moto &operator=(const Moto &);
            bool operator==(const Moto &);
            bool operator!=(const Moto &);
   
    };

}
#endif

Motofun.cpp

C++:
#include "Motolib.h"

namespace Parcheggio{

    Moto::Moto(const char *N, const char *M, const char *T) : Veicolo(N,M), Tipo(new char [strlen(T)+1]){
        strcpy(Tipo,T);
    }

    Moto::Moto(const Moto &M) : Veicolo(M), Tipo(new char [strlen(M.Tipo)+1]){
        strcpy(Tipo,M.Tipo);
    }

    void Moto::set_Tipo(const char *T){
        delete [] Tipo;
        Tipo=new char [strlen(T)+1];
        strcpy(Tipo,T);
    }

    const Moto &Moto::operator=(const Moto &M){
        if(&M!=this){
            Veicolo::operator=(M);
            if(Tipo) delete [] Tipo;
            set_Tipo(M.Tipo);
        }
    }

    bool Moto::operator==(const Moto &M){
        return (Veicolo::operator==(M) && strcmp(Tipo, M.Tipo));
    }

    bool Moto::operator!=(const Moto &M){
        return (! this->operator==(M));
    }

    ostream &operator<<(ostream &out, const Moto &M){
        return M.stampa(out);
    }

    istream &operator>>(istream &in, Moto &M){
        return M.leggi(in);
    }

    ostream &Moto::stampa(ostream &out)const {
        Veicolo::stampa(out);
        out<<"| Tipo: "<<Tipo;
        return out;
    }


    istream &Moto::leggi(istream &in){
        buffer b;
        Veicolo::leggi(in);
        in.getline(b, DIM-1, '\n');
        set_Tipo(b);
        in.ignore();
        return in;
    }

}

Garagelib.h

C++:
#ifndef GARAGELIB_H
#define GARAGELIB_H

#include "Veicololib.h"
#include "Automobilelib.h"
#include "Motolib.h"
#include "Errorelib.h"
#include <fstream>

namespace Parcheggio{
    typedef Veicolo *pntVeicolo;
    class Garage{

        private:
            static const int N=20;
            pntVeicolo Vett[N];
            static int Count;

        public:
            Garage(){for(int i=0; i<N; i++) Vett[i]=0; };
   
            bool Empty() const {return Count==0;};
            bool Full() const {return Count==N;};
   
            int Immetti(Veicolo *)throw(Errore);
            pntVeicolo Estrai(const int &);
   
            void Stampa_Video()const;
            void Stampa_File(const char *)const throw(const char *);
   

    };

}
#endif

Garagefun.c

C++:
#include "Garagelib.h"

namespace Parcheggio{

    int Garage::Count=0;

    int Garage::Immetti(Veicolo *V) throw(Errore){
        int i;
        if(strcmp(V->get_Nometipo(), "Automobile") && strcmp(V->get_Nometipo(), "Motocicletta")){
            throw(Errore(V->get_Nometipo()));
        }
        Vett[Count]=V;
        Count++;
        return Count-1;
    }

    pntVeicolo Garage::Estrai(const int &P){
        if(Count>=P){
            pntVeicolo temp= Vett[P];
            for(int i=P; i<Count; i++){
                Vett[i]=Vett[i+1];
            }
            Count--;
            return temp;
        }
    }

    void Garage::Stampa_Video()const{
        for(int i=0; i<Count; i++ ){
            cout<<i<<") "<<*Vett[i]<<endl;
        }
    }

    void Garage::Stampa_File(const char *Nome)const throw(const char *){
        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();
    }

}

Errorelib.h

C++:
#ifndef ERRORELIB_H
#define ERRORELIB_H

#include <string>

using namespace std;
namespace Parcheggio{

    class Errore{

        private :
            string error;

        public:
            Errore(string E): error(E){};
            const char *what() const;

    };

}

#endif

Errorefun.cpp

C++:
#include "Errorelib.h"

namespace Parcheggio{

const char *Errore::what() const {
    string msg;
    msg = "\n Errore! Il veicolo inserito non è valido: " + error;
    return msg.c_str();
}

}

Supportolib.h

C++:
#ifndef SUPPORTOLIB_H
#define SUPPORTOLIB_H

#include "Veicololib.h"

namespace Parcheggio{

    typedef char *Str;
    void Stampa_Menu();
    char *Copia(char *);
}
#endif

Supportofun.cpp

C++:
#include "Supportolib.h"

namespace Parcheggio{

    void Stampa_Menu(){
        cout<<"/***Benvenuti all'interno del garage**/\n\n";
        cout<<"[0] Uscita \n";
        cout<<"[1] Insersci un veicolo nel garage \n";
        cout<<"[2] Estrai un veicolo dal garage \n";
        cout<<"[3] Stampa a video la lista dei veicoli \n";
        cout<<"[4] Stampa su file la lista dei veicoli \n";
        cout<<"Premi il tasto per scegliere l'operazione da svolgere : ";

    }

    char *Copia(char *buffer){
        cin.getline(buffer, DIM-1, '\n');
        s=new char [strlen(buffer)+1];
        strcpy(s, buffer);
        cin.ignore();
    }
}

main.cpp

C++:
#include <iostream>
#include <cstdlib>
#include <fstream>

#include "Veicololib.h"
#include "Automobilelib.h"
#include "Motolib.h"
#include "Garagelib.h"
#include "Errorelib.h"
#include "Supportolib.h"

using namespace std;
using namespace Parcheggio;


int main(int argc, char** argv) {
    int opzione;
    Garage G;
    buffer b;
    do{
        system("cls");
        Stampa_Menu();
        cin>>opzione;
   
        switch(opzione){
   
            case(1):
                cout<<"\n Inserisci un Automobile o una Motocicletta [A/M] : ";
                char risp;
                cin>>risp;
                if(!G.Full()){
                    if(risp=='A'){
                        cin.ignore();
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        Str s1=Copia(b);
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        Str s2=Copia(b);
                        try{
                            G.Immetti(new Automobile("Automobile", s1, s2));\\ scusate l'ignoranza ma s1 e s2 si sono trasformati in dati dell'oggetto?
                            delete [] s1; \\quindi non potrei de allocarli cosi?
                            delete [] s2;
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }else if(risp=='M'){
                        cin.ignore();
                        cout<<"\n Inserisci la marca della Motocicletta: ";
                        Str s3=Copia(b);
                        cout<<"\n Inserisci il tipo di Motocilcetta: ";
                        Str s4=Copia(b);
                        try{
                            G.Immetti(new Moto("Motocicletta", s3, s4)); \\ scusate l'ignoranza ma s1 e s2 si sono trasformati in dati dell'oggetto?
                            delete [] s3; \\quindi non potrei de allocarli cosi?
                            delete [] s4;
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }
                }else{
                    cout<<"\n Il Garage è pieno \n";
                }
            break;
       
            case(2):
                cin.ignore();
                cout<<"\n Inserisci la posizione del veicolo da estrarre: ";
                if(!G.Empty()){
                    int pos;
                    cin>>pos;
                    cin.ignore();
                    cout<<"\n Il veicolo estratto è :";
                    cout<<endl<<G.Estrai(pos)<<endl;
                    cout<<"\n il garage adesso è composto dai seguenti veicoli: ";
                    G.Stampa_Video();
                }else{
                    cout<<"\n Il garage è vuoto \n ";
                }
            break;
       
            case(3):
                cout<<"\n Lista dei veicoli presenti nel garage: ";
                if(!G.Empty()){
                    G.Stampa_Video();
                }else cout<<"\n Il garage è vuoto \n ";
                break;
       
            case(4):
                cin.ignore();
                cout<<"\n Inserisci il Percorso del file: ";
                cin.getline(b, DIM-1, '\n');
                try{
                    G.Stampa_File(b);
                }catch(const char *b){
                    cout<<b<<endl;
                }
                break;
           
        }
        system("pause");
    }while(opzione!=0);
    return 0;
}
Post unito automaticamente:

Che ne pensate di quest'altra soluzione?
C++:
int main(int argc, char** argv) {
    int opzione;
    Garage G;
    buffer b;
  
    do{
        system("cls");
        Stampa_Menu();
        cin>>opzione;
      
        switch(opzione){
      
            case(1):
                cout<<"\n Inserisci un Automobile o una Motocicletta [A/M] : ";
                char risp;
                cin>>risp;
                if(!G.Full()){
                    if(risp=='A'){
                        cin.ignore();
                        Automobile Atemp;
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Marca(b);
                        cin.ignore();
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Alimentazione(b);
                        cin.ignore();                      
                        try{
                            G.Immetti(new Automobile("Automobile", Atemp.get_Marca(), Atemp.get_Alimentazione()));
                            Atemp.~Automobile();
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }else if(risp=='M'){
                        cin.ignore();
                        Moto Mtemp;
                        cout<<"\n Inserisci la marca della Motocicletta: ";
                        cin.getline(b, DIM-1, '\n');
                        Mtemp.set_Marca(b);
                        cin.ignore();
                        cout<<"\n Inserisci il tipo di Motocilcetta: ";
                        cin.getline(b, DIM-1, '\n');
                        Mtemp.set_Tipo(b);
                        cin.ignore();
                        try{
                            G.Immetti(new Moto("Motocicletta", Mtemp.get_Marca(), Mtemp.get_Marca()));
                            Mtemp.~Moto();
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }
                }else{
                    cout<<"\n Il Garage è pieno \n";
                }
            break;

Però mi si blocca qui:
Visualizza allegato 324657
Lascia stare la seconda soluzione, non ha senso e addirittura chiami il distruttore manualmente.

Quella suggerita da BrutPitt è la migliore
 

BrutPitt

Utente Attivo
1,166
1,262
Nella funzione Copia ... manca :
return s;
(fai il copia e incolla di quella che ti avevo scritto) :D
Se non ritorni il puntatore (il valore dell'indirizzo di memoria che hai allocato)... non passi nulla alla classe Automobile
(o meglio passi dei valori casuali, non specificati)

Ma ce li hai i WARNINGs del compilatore abilitati al livello massimo?
(A parte che il return mancante dovrebbe essere segnalato comunque.)

Sono importanti, soprattutto per chi inizia!

EDIT:
Per la deallocazione di s1 e s2 ... va bene dove li stai deallocando:
C:
G.Immetti(new Automobile("Automobile", s1, s2));\\ scusate l'ignoranza ma s1 e s2 si sono trasformati in dati dell'oggetto?
                            delete [] s1; \\quindi non potrei de allocarli cosi?
                            delete [] s2;

... perche' sia la classe Automobile che la classe Veicolo copiano i dati che passi nei propri buffers.
Non e' che si sono "trasformati" in dati dell'oggetto, ma sono stati copiati nei buffers allocati dall'oggetto (veicolo e dall'oggetto figlio automobile).
E si occupano loro (automobile e veicolo) di deallocarli alla propria "distruzione" (che immagino avvenga con la fine di visibilita' di garage ... ma non ci ho guardato con attenzione)

riEDIT:
Volendo... potresti usare anche la seconda soluzione, ma:
C:
                  f(risp=='A'){
                        cin.ignore();
                        Automobile Atemp;
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Marca(b);
                        cin.ignore();
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Alimentazione(b);
                        cin.ignore();                 
                        try{
                            G.Immetti(new Automobile("Automobile", Atemp.get_Marca(), Atemp.get_Alimentazione()));
                            // se usi questa strada... conviene magari e' piu' elegante :
                            // Atemp.set_Nometipo("Automobile"); -> fatta in precedenza, non serve in "try"
                            // G.Immetti(new Automobile( Atemp));
                            // questo invece:
                            // Atemp.~Automobile();  NO!!! e' inutile
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    } // Atemp si dealloca da sola qui -> fine visibilita'

Ma a questo punto se non DEVI usare un'allocazione dinamica... e vuoi solo pratico... basta che tu faccia:
C:
                  f(risp=='A'){
                        buffer b1, b2;
                        cin.ignore();
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        cin.getline(b1, DIM-1, '\n');
                        cin.ignore();
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b2, DIM-1, '\n');
                        cin.ignore();                 
                        try{
                            G.Immetti(new Automobile("Automobile", b1, b2));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }

Adesso di opzioni ne hai almeno 4... vediamo se riesci a farlo funzionare!!!! ;)
 
Ultima modifica:
  • Mi piace
Reazioni: Mr.Cobra

Mr.Cobra

Nuovo Utente
69
1
Nella funzione Copia ... manca :
return s;
(fai il copia e incolla di quella che ti avevo scritto) :D
Se non ritorni il puntatore (il valore dell'indirizzo di memoria che hai allocato)... non passi nulla alla classe Automobile
(o meglio passi dei valori casuali, non specificati)

Ma ce li hai i WARNINGs del compilatore abilitati al livello massimo?
(A parte che il return mancante dovrebbe essere segnalato comunque.)

Sono importanti, soprattutto per chi inizia!

EDIT:
Per la deallocazione di s1 e s2 ... va bene dove li stai deallocando:
C:
G.Immetti(new Automobile("Automobile", s1, s2));\\ scusate l'ignoranza ma s1 e s2 si sono trasformati in dati dell'oggetto?
                            delete [] s1; \\quindi non potrei de allocarli cosi?
                            delete [] s2;

... perche' sia la classe Automobile che la classe Veicolo copiano i dati che passi nei propri buffers.
Non e' che si sono "trasformati" in dati dell'oggetto, ma sono stati copiati nei buffers allocati dall'oggetto (veicolo e dall'oggetto figlio automobile).
E si occupano loro (automobile e veicolo) di deallocarli alla propria "distruzione" (che immagino avvenga con la fine di visibilita' di garage ... ma non ci ho guardato con attenzione)

riEDIT:
Volendo... potresti usare anche la seconda soluzione, ma:
C:
                  f(risp=='A'){
                        cin.ignore();
                        Automobile Atemp;
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Marca(b);
                        cin.ignore();
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b, DIM-1, '\n');
                        Atemp.set_Alimentazione(b);
                        cin.ignore();               
                        try{
                            G.Immetti(new Automobile("Automobile", Atemp.get_Marca(), Atemp.get_Alimentazione()));
                            // se usi questa strada... conviene magari e' piu' elegante :
                            // Atemp.set_Nometipo("Automobile"); -> fatta in precedenza, non serve in "try"
                            // G.Immetti(new Automobile( Atemp));
                            // questo invece:
                            // Atemp.~Automobile();  NO!!! e' inutile
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    } // Atemp si dealloca da sola qui -> fine visibilita'

Ma a questo punto se non DEVI usare un'allocazione dinamica... e vuoi solo pratico... basta che tu faccia:
C:
                  f(risp=='A'){
                        buffer b1, b2;
                        cin.ignore();
                        cout<<"\n Inserisci la marca dell'Automobile: ";
                        cin.getline(b1, DIM-1, '\n');
                        cin.ignore();
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b2, DIM-1, '\n');
                        cin.ignore();               
                        try{
                            G.Immetti(new Automobile("Automobile", b1, b2));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }

Adesso di opzioni ne hai almeno 4... vediamo se riesci a farlo funzionare!!!! ;)
Bruttpitt grazie mille sei stato di grande aiuto ho usato la prima soluzione con Atemp ecc... Vi chiedo un ultima cosa se vi va, vorrei complicarmi la vita vedo che la gestione dell'errore in pratica è finta non si attiva mai. Ho pensando ad una soluzione ed ho unito e modificato la seconda soluzione con la prima, è un pò bruttina sinceramente perchè fa due volte la domanda su che tipo di veicolo si è inserito ma non ho pensato a nulla di meglio.
Ho trovato praticamente questo un problema :

C++:
#include <iostream>
#include <cstdlib>
#include <fstream>

#include "Veicololib.h"
#include "Automobilelib.h"
#include "Motolib.h"
#include "Garagelib.h"
#include "Errorelib.h"
#include "Supportolib.h"

using namespace std;
using namespace Parcheggio;


int main(int argc, char** argv) {
    int opzione;
    Garage G;
    buffer b;
    char risp1[]="Automobile";
    char risp2[]="Motocicletta";
    char risp3;
    do{
        system("cls");
        Stampa_Menu();
        cin>>opzione;
        
        switch(opzione){
        
            case(1):
                cout<<"\n Inserisci il tipo di Veicolo : ";
                cin.getline(b, DIM-1, '\n');
                if(!G.Full()){
                        Veicolo Vtemp;
                        Vtemp.set_Nometipo(b);
                        cin.ignore();
                        cout<<"\n Inserisci la marca del Veicolo: ";
                        cin.getline(b, DIM-1, '\n');
                        Vtemp.set_Marca(b);
                        cin.ignore();
                        cout<<"Hai inserito un Automobile o una Moto?[A/M]: ";
                        cin>>risp3;
                        if(risp3=='A'){
                        Automobile Atemp;
                        buffer b2;
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b2, DIM-1, '\n');
                        Atemp( Vtemp.get_Nometipo(), Vtemp.get_Marca(), b2);
                        cin.ignore();                       
                        try{
                            G.Immetti(new Automobile(Atemp));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }else if(risp3=='M'){
                        Moto Mtemp;
                        buffer b3;
                        cout<<"\n Inserisci il tipo di Motocilcetta: ";
                        cin.getline(b3, DIM-1, '\n');
                        Mtemp( Vtemp.get_Nometipo(), Vtemp.get_Marca(), b3);
                        cin.ignore();
                        try{
                            G.Immetti(new Moto(Mtemp));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }
                }else{
                    cout<<"\n Il Garage è pieno \n";
                }
            break;

Immagine.png
 

_Achille

Utente Èlite
3,067
725
CPU
Intel i5-6600K @4.6 GHz
Dissipatore
Cryorig H5
Scheda Madre
ASRock Z170 Extreme 6
HDD
WesternDigital 1TB & Crucial MX200 250GB
RAM
Corsair Ven 16GB DDR4 2133MHz
GPU
Sapphire RX 580 Nitro+
Monitor
Dell S2418H
PSU
RM550X
Case
NZXT S340
Periferiche
Anne Pro 2, Razer Abyssus
OS
Windows 10 Pro
Bruttpitt grazie mille sei stato di grande aiuto ho usato la prima soluzione con Atemp ecc... Vi chiedo un ultima cosa se vi va, vorrei complicarmi la vita vedo che la gestione dell'errore in pratica è finta non si attiva mai. Ho pensando ad una soluzione ed ho unito e modificato la seconda soluzione con la prima, è un pò bruttina sinceramente perchè fa due volte la domanda su che tipo di veicolo si è inserito ma non ho pensato a nulla di meglio.
Ho trovato praticamente questo un problema :

C++:
#include <iostream>
#include <cstdlib>
#include <fstream>

#include "Veicololib.h"
#include "Automobilelib.h"
#include "Motolib.h"
#include "Garagelib.h"
#include "Errorelib.h"
#include "Supportolib.h"

using namespace std;
using namespace Parcheggio;


int main(int argc, char** argv) {
    int opzione;
    Garage G;
    buffer b;
    char risp1[]="Automobile";
    char risp2[]="Motocicletta";
    char risp3;
    do{
        system("cls");
        Stampa_Menu();
        cin>>opzione;
       
        switch(opzione){
       
            case(1):
                cout<<"\n Inserisci il tipo di Veicolo : ";
                cin.getline(b, DIM-1, '\n');
                if(!G.Full()){
                        Veicolo Vtemp;
                        Vtemp.set_Nometipo(b);
                        cin.ignore();
                        cout<<"\n Inserisci la marca del Veicolo: ";
                        cin.getline(b, DIM-1, '\n');
                        Vtemp.set_Marca(b);
                        cin.ignore();
                        cout<<"Hai inserito un Automobile o una Moto?[A/M]: ";
                        cin>>risp3;
                        if(risp3=='A'){
                        Automobile Atemp;
                        buffer b2;
                        cout<<"\n Inserisci l'alimentazione dell'Automobile: ";
                        cin.getline(b2, DIM-1, '\n');
                        Atemp( Vtemp.get_Nometipo(), Vtemp.get_Marca(), b2);
                        cin.ignore();                      
                        try{
                            G.Immetti(new Automobile(Atemp));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }else if(risp3=='M'){
                        Moto Mtemp;
                        buffer b3;
                        cout<<"\n Inserisci il tipo di Motocilcetta: ";
                        cin.getline(b3, DIM-1, '\n');
                        Mtemp( Vtemp.get_Nometipo(), Vtemp.get_Marca(), b3);
                        cin.ignore();
                        try{
                            G.Immetti(new Moto(Mtemp));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }
                    }
                }else{
                    cout<<"\n Il Garage è pieno \n";
                }
            break;

Visualizza allegato 324706
Comunque faccio veramente fatica a leggere il codice, è identato malissimo.
Inoltre non dovresti utilizzare DevC++ perché non più supportato.

Ti sta dicendo semplicemente che non riesce a trovare una funzione Parcheggio::Automobile(const char *, const char *, Parcheggio::buffer), quindi il problema sta tra gli argomenti della chiamata, ed esso è buffer. Se invece di passargli buffer passi &buffer[0] il problema dovrebbe risolversi.

Inoltre non ti servono 77 buffer, te me basta uno. E in più vista la scelta di un veicolo temporaneo implementerei un costruttore rvalue reference per utilizzare std::move()
 
  • Mi piace
Reazioni: Mr.Cobra

BrutPitt

Utente Attivo
1,166
1,262
Se vuoi correggere quello ci vuole un cast su b2 e b3 ...
... riesci da solo? ;)

Se usi Veicolo, a questo punto pero' non e' piu' una buona idea usare "anche" Atemp ... perche' fai un fai un giro vizioso...
Nel senso che Veicolo e' genitore di Auto e Moto ... e se inizializzi Auto, inizializzi anche Veicolo, ma non viceversa... e tu adesso hai inizializzato Veicolo... con Atemp inizializzeresti Auto e (un altro) Veicolo... per poi reinizializzare un'altra Automobile (e un altro Veicolo)

Quindi se percorri questa nuova strada, ti consiglio di non usare piu' Atemp... e di fare direttamente l'inizializzazione con:
C:
                        try{
                            G.Immetti(new Automobile(Vtemp.get_Nometipo(), Vtemp.get_Marca(), /* col cast */ b2));
                        }
                        catch(Errore e){
                            cout<<e.what()<<endl;
                        }

Aiuto sul cast:
Vedi che tipo di dato e' il terzo parametro di Automobile, e fai il cast di b2 a quel tipo di dato
Post unito automaticamente:

Fino adesso ti sto dicendo come "risolvere" i problemi, ma vedo che hai molta confuzione.
Quello che hai scelto, non e' il metodo migliore... mi riferisco al fatto di inizializzare una classe "madre" ed utilizzarla per inizializzare la classe "figlio" (che a sua volta inizilaizza un'altra classe "madre").

La cosa piu' "elegante", proposta da te, e discussa fin ora, era la funzione Copia ... che serviva per acquisire gli input e inizializzare Automobile/Moto
(e la puoi usare anche a "monte" della scelta auto/moto, come adesso stai usando Veicolo).

Un altro metodo che ti accenno (solo!) e':
C:
    Automobile *auto = new Automobile;
   // poi acquisici gli input e usi set_Nometipo(), set_Marca()... etc per definire i membri di "auto"
   // ed infine la "immetti" nel "garage"

Gli altri sono dei metodi per evitare di usare gli oeratori di allocazione/deallocazione dinamica (sia con gli "array" che con le classi)... e si vede!!! ... nel senso che il professore lo notera'.

Comunque faccio veramente fatica a leggere il codice, è identato malissimo.
Inoltre non dovresti utilizzare DevC++ perché non più supportato.

Ti sta dicendo semplicemente che non riesce a trovare una funzione Parcheggio::Automobile(const char *, const char *, Parcheggio::buffer), quindi il problema sta tra gli argomenti della chiamata, ed esso è buffer. Se invece di passargli buffer passi &buffer[0] il problema dovrebbe risolversi.

Inoltre non ti servono 77 buffer, te me basta uno. E in più vista la scelta di un veicolo temporaneo implementerei un costruttore rvalue reference per utilizzare std::move()

Fai benissimo a dirgli cosa sarebbe meglio usare!
Il fatto e' che quelle classi gli sono state fornite come "libreria", quindi non possono essere modificate... tutt'al piu' puo' derivarsi una propria classe... ma credo che l'argomento classi sia stato appena introdotto, e ne stia acquisendo i primi mneccanismi.
Oltretutto, come hai notato, e' ancora indeciso sull'allocazione dinamica e sulla visibilita' delle variabili locali, e non credo sia ancora in grado di "derivarsi" una classe atta a gestirsi le proprie necessita.

Ma poi le classi sono fatte "bene" (o meglio, adatte allo scopo), hanno costruttori, operatori di copia... etc... solo che non utilizzano la "std"... perche' probabilmente non 'e' stata ancora introdotta nel corso.

Credo che sia cosi' anche per cio' che riguarda il DevC++, immagino che sia stato anche quello un "input" del corso.
Ovviamente se vorra' fare domando riguardo altri compilatori, saremo ben lieti di fornigli risposte ;) ... ma quello iniza ad essere un desiderio personale, che va al di la' della necessita' di "far funzionare" un esercizio.

P.S.
Inizio a darti ragione anche per i "cin.ignore()" che qui dovrebbero essere usati SOLO prima di un cin.getline() ... non sono inutili, ma qui vengono messi un po' ovunque... :D
 
Ultima modifica:
Stato
Discussione chiusa ad ulteriori risposte.

Entra

oppure Accedi utilizzando
Discord Ufficiale Entra ora!