Newsgroup: it.comp.lang.c++
Titolo: serializzare su uno stream

in java esiste il concetto di serializzazione, cioè la possibilità di
scrivere un oggetto su uno stream e poi di rileggerlo da esso...
mi interessava avere questa caratteristica per un paio di classi in
c++ e mi sono trovato a dover scegliere tra le seguenti possibilità:
1) creare due funzioni:
void serializza(const miaclasse& Oggetto, ostream Stream);
void carica(miaclasse& Oggetto, istream Stream);
2) mettere un operator string nella mia classe, in modo che quando ad
uno stream faccio
Stream << MioOggetto;
venga richiamato l'operator string (viene richiamato quello?!?) che
restituisce una rappresentazione serializzata del mio oggetto
problema: e per l'input?
Stream >> MioOggetto;???
3) fare come in java, cioè creare una funzione toString nella
miaclasse
1 e 3 non mi piacciono molto, io propenderei per la 2, voi che ne
dite?
-- 
]\/[ad]\/[age (
www.mindreamz.net
)
"Un Maestro insegue semplicemente la sua visione di Eccellenza in
qualunque cosa sta facendo e lascia agli altri decidere se sta 
lavorando o giocando. A lui sembra sempre di fare entrambe." - Anonimo

 wrote in message
news:a5ainvcf8ar165815...@4ax.com...

Se devi serializzare in modalita' testo, quindi il tuo output/inoput sono in
formato testo io utilizzerei gli operatori '>>' e '<<' piu' o meno nel
seguente modo:
////// serializzazione modalita' testo - modo 1 (preferito)
class character
{
public:
   character() {};
   character(std::string charName) : name(charName) {}
   virtual ~character() {};
   std::string getCharName();
private:
   friend std::ostream& operator << (std::ostream& s, const character& c);
   friend std::istream& operator >> (std::istream& s, character& c);
   std::string name;
   int age;
};
std::ostream& operator << (std::ostream& s, const character& c)
{
   ////// ...
   return s;
}
std::istream& operator >> (std::istream& s, character& c)
{
   ////// ...
   return s;
}
int main()
{
   std::ofstream ofile("game.dat");
   character c1("pippo");
   ofile << c1;
   ofile.close();
   std::ifstream ifile("game.dat");
   character c2;
   ifile >> c2;
   ifile.close();
   return 0;
}
////// serializzazione modalita' testo - modo 2
class character
{
public:
   character() {};
   character(std::string charName) : name(charName) {}
   virtual ~character() {};
   std::string getCharName();
   std::ostream& operator >> (std::ostream& s);
   std::istream& operator << (std::istream& s);
private:
   std::string name;
   int age;
};
std::ostream& character::operator >> (std::ostream& s)
{
   ////// ...
   return s;
}
std::istream& character::operator << (std::istream& s)
{
   ////// ...
   return s;
}
int main()
{
   std::ofstream ofile("game.dat");
   character c1("pippo");
   c1 >> ofile;
   ofile.close();
   std::ifstream ifile("game.dat");
   character c2;
   c2 << ifile;
   ifile.close();
   return 0;
}
Se devi serializzare in modalita' binaria, quindi il tuo output/inoput sono
in formato binario io utilizzerei due funzioni tipo write_object() e
read_object() piu' o meno nel seguente modo:
////// serializzazione modalita' binaria
class character
{
public:
   character() {};
   character(std::string charName) : name(charName) {}
   virtual ~character() {};
   std::string getCharName();
   std::ostream& write_object(std::ostream& s);
   std::istream& read_object(std::istream& s);
private:
   std::string name;
   int age;
};
std::ostream& character::write_object(std::ostream& s)
{
   ////// ...
   return s;
}
std::istream& character::read_object(std::istream& s)
{
   ////// ...
   return s;
}
int main()
{
   std::ofstream ofile("game.dat");
   character c1("pippo");
   c1.write_object(ofile);
   ofile.close();
   std::ifstream ifile("game.dat");
   character c2;
   c2.read_object(ifile);
   ifile.close();
   return 0;
}
Il tema della serializzazione e' un po' piu' lungo di quanto ho cercato di
riassumere con questi esempi.
Se si utilizza una serializzazione binaria bisognerebbe tenere conto del
byte order (bin endian/little endian) e quindi fornire un minimo di supporto
per il marshaling dei dati.
Si potrebbe utilizzare una classe base 'Serializable' stile Java (non
astratta pura) che oltre a obbligarti nella ridefinizione di write_object()
e read_object() fornirebbe alcune funzioni di supporto.
A questo link trovi alcune informazioni utili a risolvere il problema della
serializzazione.
http://www.parashift.com/c++-faq-lite/serialization.html
Spero di esserti stato di aiuto
Fabio Angelini
http://www.fabioangelini.com