Zapis i odczyt struktur z plików binarnych to pestka a co z klasami gt;
T72
Umiesz już zapisać do pliku binarnego strukture i ją wczytać? A co z klasą która ma również metody? Jest łatwy sposób otóż mamy sobie klase:
class osoba
{
private:
int liczba;
char imie[50];
double srednia;
public:
osoba(void){};
osoba(int l, char * i, double s) : liczba(l), srednia(s)
{
strcpy(imie, i);
}
void zapisz(void);
void odczytaj(void);
void pokaz(void);
};
I chcemy żeby funkcja zapisz i odczytaj pracowały na plikach binarnych. Tak więc robimy tak:
void osoba::zapisz(void)
{
fstream plik;
plik.open("osoba.bin", ios::out | ios::binary);
plik.write((char*)this,sizeof(int)+sizeof(double) + sizeof(char)*50+2 );
plik.close();
}
Czyli zapis klasy różni się od zapisu struktury tylko miejscem gdzie podajemy rozmiar. Trzeba tam podać sumy rozmiarów wszystkich zmiennych które sa w klasie + jeszcze 2 czyli: sizeof(int) bo int liczba sizeof(double) bo double srednia sizeof(char)*50 bo char imie[50] no i na końcu + 2 :) odczyt analogicznie:
void osoba::odczytaj(void)
{
fstream plik;
plik.open("osoba.bin", ios::in | ios::binary);
plik.read((char*)this,sizeof(int)+sizeof(double) + sizeof(char)*50+2);
plik.close();
}
a do czego to wogole sluzy ? :)
Temporal: nie, chwila. Zapisujemy DANE (pola) klasy, struktury, a nie logikę ich działania :]
sizeof(obiekt) wystarczy jeśli robimy zrzut pamięci obiektu (jakkolwiek ja wiem, że to wielka lipa).
Żadne vtable, żadne type info, żadne this, żadne metody nie muszą zostać zapisane, a niektóre to po prostu niemożliwość żeby zapisać!
Niektóre skomplikowane przypadki (struktury ze wskaźnikami, drzewami, cyklami, połączeniami (w sensie związków)) są tu: http://www.parashift.com/c++-faq-lite/serialization.html
Radzę przeczytać!
Oj, nie wystarczy zwykłe sizeof(obiekt). Nie wystarczało już w C, gdzie pracuje się tylko na zwykłych pakietach zmiennych, zwanych też strukturami. Nie wystarcza więc to i w C++, gdzie oprócz zmiennych, mamy w klasie funkcje, oraz vtable, czyli tablicę funkcji wirtualnych (i jeszcze jest wskaźnik na type info, potrzebne do typeid() i dynamic_cast, ale to można wyłączyć w kompilatorze). Oprócz tego, każda zmienna składowa może być klasą, z własnymi zmiennymi, funkcjami, etc. Ogółem, ta metoda zapisu może się przydać, jeżeli ktoś ma zamiar pisać gry na PlayStation, czy inne konsole - na większości można zagwarantować, że po ponownym uruchomeniu gry/programu układ pamięci będzie taki sam. Niestety, na komputerach PC jest to bardzo mało prawdopodobne, i już z tego powodu nie wolno zapisywać wskaźników, bo po ich wczytaniu wynik działania programu jest niezdefiniowany [czyli może działać dobrze, a nawet lepiej ^^, albo sformatować dysk, wysyłając wcześniej dużo sprośnych e-maili do wszystkich przyjaciół w książce adresowej]. Do tego wszystkiego dochodzą jeszcze problemy z wyrównywaniem w pamięci, o których wspomniał MarcinEc. Jednak nie do końca zgadzam się z punktem 1 jego komentarza. Struktury i klasy nie różnią się niczym, ale w C++. Między strukturą w C, a klasą/strukturą w C++ różnic jest już bardzo dużo (część wspomniałem wyżej). Pozdrawiam.
wystarczy sizeof(nazwa_obiektu), policzy to dokładny rozmiar danych w obiekcie i to niezależnie od ustawień kompilatora... w końcu po to To jest!
Hmmm...
No to wtedy metoda jest zmienną i jej wartość można również zapisać (adres do procedury) . Chyba się nie myle ??
A co jak tabice będą dynamiczne, bo tym sposobem to odczytuje tylko śmieci???
A co to jest kalsa?
wiesz, może kup sobię jakąś książkę??
ale mógłbyś wyjaśnić również po co to +2... (się domyślam, ale artykuł jest przez to niekompletny).
Nie łatwiej wewnątrz klasy stworzyć strukturę ? Przecież zależnie od kompilatora, w klasie dane nie muszą byc w zaden sposob ułozone liniowo jedna za drugą.