Stai usando un browser non aggiornato. Potresti non visualizzare correttamente questo o altri siti web. Dovreste aggiornare o usare un browser alternativo.
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?
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.
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
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.
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.
#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;
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.
#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;
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:
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:
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;
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;
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()
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:
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