Controlla un pò le modifiche e chiedi se non capisci qualcosa.
#include <iostream>
#include <fstream>
#include <exception>
using namespace std;
class Error
{
private:
char* msg;
public:
Error(char* _msg) : msg(new char[strlen(_msg)+1]) { strcpy(msg,_msg); }
Error(const Error & rhs)
{
msg = new char[strlen(rhs.msg) + 1];
strcpy(msg,rhs.msg);
}
~Error() { delete [] msg; }
char* what() { return msg; }
};
class Libro
{
private:
char *autori;
char *titolo;
int anno;
public:
Libro (char *Autori="", char *Titolo="", int Anno=0) : autori(new char[strlen(Autori)+1]), titolo(new char[strlen(Titolo)+1]), anno(Anno)
{
strcpy(autori,Autori);
strcpy(titolo,Titolo);
}
~Libro() { delete [] autori; delete [] titolo; }
char* get_autori() { return autori; }
char* get_titolo() { return titolo; }
int get_anno() { return anno; }
void stampa()
{
cout << *this;
}
friend istream& operator >> (istream& file, Libro& libro) throw (Error)
{
if(!file)
{
throw Error("\nApertura in lettura non riuscita\n");
}
else
{
char *temp = new char[256];
if(file.getline(temp,256))
{
char * ptr = strstr(temp,"Autore: ");
if(ptr)
{
ptr += 8;
libro.autori = new char[strlen(ptr) + 1];
strcpy(libro.autori,ptr);
}
file.getline(temp,256);
ptr = strstr(temp,"Titolo: ");
if(ptr)
{
ptr += 8;
libro.titolo = new char[strlen(ptr) + 1];
strcpy(libro.titolo,ptr);
}
file.getline(temp,256);
ptr = strstr(temp,"Anno: ");
if(ptr)
{
ptr += 6;
libro.anno = atoi(ptr);
}
delete [] temp;
}
}
return file;
}
friend ostream& operator << (ostream& file, const Libro& libro) throw (Error)
{
if(!file)
{
throw Error("\nApertura in scrittura non riuscita\n");
}
else
{
file << static_cast<const char *>("Autore: ") << libro.autori << endl;
file << static_cast<const char *>("Titolo: ") << libro.titolo << endl;
file << static_cast<const char *>("Anno: ") << libro.anno << endl;
}
return file;
}
};
class Lista
{
class Nodo
{
public:
Libro* l;
Nodo* next;
Nodo(Libro* _l=0, Nodo* _n=0) : l(_l), next(_n) {};
~Nodo(){};
};
private:
Nodo* head;
public:
Lista(Nodo* _n=0): head(_n) {};
Lista(char *fname)
{
head = 0;
ifstream file(fname, ios::in);
Libro *l = new Libro();
while(file >> *l)
{
inserisci(l);
l = new Libro();
}
delete l;
file.close();
};
~Lista()
{
Nodo *temp=head;
while(temp!=0) //Scorre tutta la lista...
{
head=head->next; //...facendo scorrere in avanti first
delete temp; //e cancellando il precedente,
temp=head; //fino all'ultimo elemento.
}
}
void inserisci(Libro* l)
{
Nodo *p = new Nodo(l,0);
if(head != 0)
{
p->l=l;
p->next = head;
head = p;
}
else
{
p->next = 0;
head = p;
}
}
void salva(char *fname) throw (Error)
{
try
{
ofstream file (fname, ios::out);
Nodo *temp = head;
while(temp!=0)
{
file << *(temp->l);
temp = temp->next;
}
file.close();
}
catch(Error & e)
{
throw;
}
}
void stampa()
{
Nodo *temp = head;
while(temp!=0)
{
temp->l->stampa();
temp=temp->next;
}
}
};
int main()
{
Lista l1; /* crea una lista vuota */
Libro* libro;
libro = new Libro("Lev Tolstoj", "Guerra e pace", 1865);
l1.inserisci(libro);
libro = new Libro("Giovanni Verga", "I Malavoglia", 1881);
l1.inserisci(libro);
cout << "Contenuto di l1:" << endl;
l1.stampa();
try
{
l1.salva("libri.dat"); /* salva su file */
}
catch (Error & e)
{
cout << e.what() << endl;
}
Lista l2("libri.dat");
libro = new Libro("Walter Scott", "Ivanhoe", 1819);
l2.inserisci(libro);
cout << "Contenuto di l2:" << endl;
l2.stampa();
}
Il prof non usa il keyword const vedo, e sta cosa non è un bene. Non so chi ha fatto la classe Error ma la fatto male. La classe deve avere il costruttore di copia se no il catch cattura casini.
Leggi sto paragrafo:
specialmente il 17.17
Objects that are thrown must have a publicly accessible copy-constructor. The compiler is allowed to generate code that copies the thrown object any number of times, including zero. However even if the compiler never actually copies the thrown object, it must make sure the exception class's copy constructor exists and is accessible.
Ma lo sa il prof che esiste la classe string, ancora con i char * continua?