|
Programiranje Programski jezici, tehnike, alatke... |
|
Alatke vezane za temu | Vrste prikaza |
19.6.2011, 15:34 | #1 |
Starosedelac
|
[C++] Binary serialization
Opet mi je bilo dosadno i igrao sam se sa serijalizacijom. Naravno, video sam ovakva rešenja:
Kod:
ofs.write((char*)&obj, sizeof(obj)); BinarySerializer.h BinarySerializer.cpp BSTest Još sam nov sa C++-om tako da je neke stvari možda bilo moguće uraditi na mnogo lakši način. Kako se ovo čudo koristi? Kod:
BinarySerializer b("filename"); b.serialize(); b << 1 << 2 << "test string"; b.deserialize(); int x, y; string test; b >> x >> y >> test; cout << x << "\n" << y << "\n" << test.c_str(); b.closeFiles(); Kod:
class neka_klasa : public ISerializable { public: // blablabla protected: void Serialize(BinarySerializer* b) { b << x << y << z; // upisujemo potrebne informacije u fajl } void Deserialize(BinarySerializer* b) { b >> x >> y >> z; // citamo iz fajla } // prazan konstruktor je potreban, ako je protected onda mora da se doda i BinarySerializer kao friend neka_klasa() { } friend class BinarySerializer; }; |
Sledeći korisnik se zahvaljuje korisniku EclipsE na korisnoj poruci: | ||
Belphegor (19.6.2011) |
19.6.2011, 21:19 | #2 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Interesantna tema i zanimljiv pristup serijalizaciji .
Probao sam malo i skratio ove dve metode: Kod:
BinarySerializer& BinarySerializer::operator<<(const std::string& str) { unsigned int size = str.size(); this->addData((char*)&size, sizeof(unsigned int)); this->addData(str.c_str(), sizeof(char) * size); return *this; } BinarySerializer& BinarySerializer::operator>>(std::string& str) { unsigned int length; this->readData(&length, sizeof(unsigned int)); /*char* c_str = new char[length + 1]; this->readData(c_str, sizeof(char) * length); c_str[length] = '\0'; str = c_str; delete c_str;*/ str.reserve(length); for(unsigned int i = 0; i < length; ++i) str.push_back(ifs.get()); return *this; } Ako uradis neke dodatke postavi. |
19.6.2011, 21:27 | #3 |
Starosedelac
|
Re: [C++] Binary serialization
Eh, tek sad vidim
Bila je greška u "BinarySerializer& BinarySerializer:: operator<<(const std::string& str)". U početku sam hteo samo da upišem string tako što ću da idem kroz slova sve do prvog '\0', i da tako zapisem string. Kod:
for (i = 0; i < size && c[i]; i++); Što se tiče čitanja, ok je samo moraš da proveriš da li je fajl otvoren za deserijalizaciju (ako odradiš b.serialize() i probaš b >> nesto, trebalo bi da baci grešku). EDIT: sad vidim, u principu i ne mora zato što će this->readData(&length, sizeof(unsigned int)); da se buni ako fajl nije otvoren za deserijalizaciju |
20.6.2011, 13:26 | #4 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Imam malih promena/poliranja i skidanja dlaka sa jajeta .
Izmenjeno 90% funkcija da budu "const-correct" i zamenjeni C-style cast-ovi u C++ cast-ove. Izmenjeno ime funkcije addData u writeData posto je ova druga readData pa rek'o... Imao sam samo jedan problem kod jedne funkcije gde sam morao da "skinem" const type clarifier da bi radilo: Kod:
void BinarySerializer::writeData(const char* ptr, unsigned size) const { assert(mode == 1); const_cast<std::ofstream& >(ofs).write(ptr, size); } BinarySerialization.cpp BSTest.cpp Mislim da nisam nista prevideo, ako jesam javi. EDIT: Uuuuups. ima jedan cast previse: Kod:
void BinarySerializer::readData(char* ptr, unsigned size) { assert(mode == 2); //ifs.read(reinterpret_cast<char*>(ptr), size); ifs.read(ptr, size); } Poslednja ispravka: Belphegor (20.6.2011 u 13:44) |
Sledeći korisnik se zahvaljuje korisniku Belphegor na korisnoj poruci: | ||
EclipsE (20.6.2011) |
20.6.2011, 19:32 | #5 |
Starosedelac
|
Re: [C++] Binary serialization
Ne znam kako da serializujem map :\
Kada odradim nesto kao: Kod:
template <typename T, typename Y> const BinarySerliazer& operator<<(const std::map<T, Y*>& mmap) const { } Kod:
template <typename T> const BinarySerializer& operator<<(const std::map<T, ISerializable*>& mmap) const { } |
20.6.2011, 19:43 | #6 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Mislis ne vidis sve clanove posle access operatora?
I kod mene je zabagovan VS tako da se ne oslanjam mnogo na intellisense. |
20.6.2011, 20:08 | #7 |
Starosedelac
|
Re: [C++] Binary serialization
Ma VS je totalno poludeo
|
20.6.2011, 20:13 | #8 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Ja sam sad nesto probao da kompajliram i napola:
|
20.6.2011, 20:26 | #9 |
Starosedelac
|
Re: [C++] Binary serialization
To se i meni desilo
Morao sam da obrišem sve iz /Debug/ i /ipch/ da bi hteo normalno da kompajlira. |
20.6.2011, 20:43 | #10 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Probao sam sto si rekao ali kod mene ne pomaze.
Napravio sam novi projekat i probao slicno i ne puca kompajler, sad cu da vidim postepeno 'de ga tacno boli. |
20.6.2011, 20:44 | #11 |
V.I.P. Zaštita
Član od: 30.9.2007.
Lokacija: Hypnos Control Room, Tokyo Metropolitan Government Building
Poruke: 5.914
Zahvalnice: 1.181
Zahvaljeno 1.320 puta na 1.094 poruka
|
Re: [C++] Binary serialization
Imate li instalirane sve zakrpe za VS koje su izašle? AKo ne, pravac Windows Update.
|
20.6.2011, 20:53 | #12 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Ako imas VS probaj kod sebe da ubacis u klasu:
Kod:
template <typename T, typename Y> const BinarySerliazer& operator << ( const std::map< T, Y* > & mmap ) const { } EDIT: Nasao sam zasto puca, kopirao sam parce koda od EclipsE-a, pazi na ime tipa koji vraca: Kod:
template <typename T, typename Y> const BinarySerliazer& operator<<(const std::map<T, Y*>& mmap) const { } Kod:
BinarySerializer Poslednja ispravka: Belphegor (20.6.2011 u 21:26) |
20.6.2011, 21:50 | #13 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Mislim da je ovo sto se tice std::map kontenera
Kod:
template <typename T, typename Y> const BinarySerializer& operator << (const std::map< T, Y* > & mmap) const { unsigned int size = mmap.size(); this->writeData(reinterpret_cast<char*>(&size), sizeof(unsigned int)); std::map<T, Y*>::const_iterator itr = mmap.begin(); for(; itr != mmap.end(); ++itr) { this->writeData(reinterpret_cast<const char*>(&(*itr).first), sizeof(T)); this->writeData(*(*itr).second); } return *this; } template <typename T, typename Y> BinarySerializer& operator >> (std::map<T, Y*>& mmap) { unsigned int size; this->readData(reinterpret_cast<char*>(&size), sizeof(unsigned int)); for(unsigned int i = 0; i < size; ++i) { T key; this->readData(reinterpret_cast<char*>(&key), sizeof(T)); Y* py = new Y(); *this >> *py; mmap[key] = py; } return *this; } sta ako je key std::string? Nista onda, se bogu da korisnik ove klase koristi samo primitivne tipove kao key. Poslednja ispravka: Belphegor (20.6.2011 u 22:06) |
21.6.2011, 0:03 | #14 |
Starosedelac
|
Re: [C++] Binary serialization
Ne znam, ne mogu da napravim samo map<std::string, bilosta> :\
A čini mi se kao da sam negde vidjao da koriste std::string za map... Evo ga nov test. |
21.6.2011, 5:57 | #15 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Jos jedna misao pre nego krenem na posao.
Moze samo da se ubace shift operatori umesto read/writeData i tako ako se ubaci neki "cudni" tip u map dobija se compile time error umesto runtime bug ako nema odgovarajueg overload-a operatora. Kod:
template <typename T, typename Y> const BinarySerializer& operator << (const std::map< T, Y* > & mmap) const { unsigned int size = mmap.size(); this->writeData(reinterpret_cast<char*>(&size), sizeof(unsigned int)); std::map<T, Y*>::const_iterator itr = mmap.begin(); for(; itr != mmap.end(); ++itr) { //this->writeData(reinterpret_cast<const char*>(&(*itr).first), sizeof(T)); *this << (*itr).first; this->writeData(*(*itr).second); } return *this; } template <typename T, typename Y> BinarySerializer& operator >> (std::map<T, Y*>& mmap) { unsigned int size; this->readData(reinterpret_cast<char*>(&size), sizeof(unsigned int)); for(unsigned int i = 0; i < size; ++i) { T key; //this->readData(reinterpret_cast<char*>(&key), sizeof(T)); *this >> key; Y* py = new Y(); *this >> *py; mmap[key] = py; } return *this; } Mada bi ja izbacio kontenere iz klase i radio to sa njima van nje i specijalizovao usko za moje potrebe. Jako je tesko napisati genericki kod koji bi resio svaku situaciju. |
21.6.2011, 12:00 | #16 |
Starosedelac
|
Re: [C++] Binary serialization
I size moze da se upise kao:
Kod:
unsigned int size = mmap.size(); *this << size; Kod:
// << template <typename T, typename Y> const BinarySerializer& operator << (const std::map< T, Y* > & mmap) const { unsigned int size = mmap.size(); *this << size; std::map<T, Y*>::const_iterator itr = mmap.begin(); for(; itr != mmap.end(); ++itr) { *this << itr->first; *this << *(itr->second); } return *this; } template <typename T, typename Y> const BinarySerializer& operator << (const std::map< T, Y > & mmap) const { unsigned int size = mmap.size(); *this << size; std::map<T, Y>::const_iterator itr = mmap.begin(); for(; itr != mmap.end(); ++itr) { *this << itr->first; *this << itr->second; } return *this; } Kod:
// >> template <typename T, typename Y> BinarySerializer& operator >> (std::map<T, Y*>& mmap) { unsigned int size; *this >> size; for(unsigned int i = 0; i < size; ++i) { T key; *this >> key; Y* py = new Y(); *this >> *py; mmap[key] = py; } return *this; } template <typename T, typename Y> BinarySerializer& operator >> (std::map<T, Y>& mmap) { unsigned int size; *this >> size; for(unsigned int i = 0; i < size; ++i) { T key; Y py; *this >> key; *this >> py; mmap[key] = py; } return *this; } |
21.6.2011, 17:34 | #17 |
V.I.P. Programiranje
Član od: 29.8.2007.
Lokacija: Valjevo
Poruke: 1.349
Zahvalnice: 983
Zahvaljeno 371 puta na 280 poruka
|
Re: [C++] Binary serialization
Mozda bi jednu stvar trebalo uzeti u obzir, sto se tice serijalizacije, posto se obicno to radi sa "malim" klasama tipa koje drze neke "atribute", jer sigurno necemo serij. resurse, a s'obzirom da su vec neko vreme u C++ standard ubaceni "Move Semantics, Rvalue References, and Perfect Forwarding" moze da se na dosta mesta izbegne dinamicko alociranje memorije, pogotovu sa malim objektima gde dolazi do fragmentacije memorije i s'tim pogorsavanje performansi, a da i ne spominjem da je pozivanje new/new[] operatora relativno spora operacija u odnosu kreiranja na stack-u a i u isto vreme te stavlja na dilemu koji objekat je odgovoran za alociranje/dealociranje i ostale probleme vezane za memoriju na heap-u, najpametnije je, normalno gde je to moguce, ostaviti alokatorima koji su implementirani u same STL kontenere.
Tako da nema vise potreba za kontenerima koji drze pokazivace, samo je potrebno implementirti odgovarajuce metode u doticne klase - move "copy" konstruktor, move asignment operator... Ja se tek jos upoznajem sa ovim inovacijama tako da ne bih jos objasnjavao o cemu se tacno radi i kako funkcionise dok to ne savladam 100%, najbolje da odgledas video sa linka koji sam ostavio, ako nisi do sada video, da vidim da li ce da te inspirise za neke nove ideje. |
Sledeći korisnik se zahvaljuje korisniku Belphegor na korisnoj poruci: | ||
EclipsE (26.6.2011) |
Bookmarks sajtovi |
|
|