jak poprawnie zserializowac obiekt ze stringiem?

0

Witam,

Czy może mi ktoś wyjaśnić, dlaczego poniższy kod serializujący obiekt klasy Encja do pliku nie działa?
Z tego co wiem, działa to na VC++ lecz pod Dev-C++ już nie.

#include <cstdlib>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

class Encja
{
public:
	Encja() : _id(0)
	{ };

	Encja(long id) : _id(id)
	{ };

	long ZwrocId() const
	{
		return _id;
	};

	void UstawNazwa(string nazwa)
	{
		_nazwa = nazwa;
	}

	string&  ZwrocNazwa()
	{
		return _nazwa;
	}
	
private:
	const long _id;
	string _nazwa;
};

int main(int argc, char *argv[])
{
	string nazwa = "Nazwa";
	bool zapis = false;


	if (zapis)	
	{
		Encja e(1);
		e.UstawNazwa(nazwa);
	
		ofstream plik("Baza.db", ios::binary);
		plik.write((char*)&e, sizeof(Encja));

		cout << e.ZwrocNazwa() << endl;
	}
	else
	{
		Encja e;
	
		ifstream plik("Baza.db", ios::binary);
		plik.read((char*)&e, sizeof(Encja));

		cout << e.ZwrocNazwa() << endl;
	}



    system("PAUSE");
    return EXIT_SUCCESS;
}
0

A "niedziałanie" objawia się ... ?

0

Pierwsze co rzuca się w oczy to brak napisu "Nazwa" w pliku do którego zapisujemy obiekt (opcja zapis = true). Skutkuje to oczywiście wczytaniem złego obiektu (opcja zapis = false) i tym samym wysypanie się programu na linijce:
cout << e.ZwrocNazwa() << endl;

Do tej pory tak zapisywałem obiekty do pliku pod VC++ i każdy string widoczny był w pliku jako napis. Pod Dev-C++ najwidoczniej obiekt std::string jest zapisywany jako... wskaźnik? Nie mam pojęcia skąd te różnice...

0

Poniżej wyjaśnienie, co też podejrzewałem ale mam teraz pewność.

You might wonder why we didn't dump the entire object to a file instead of serializing individual data members.

No, we couldn't. There are at least two problems with this approach. Usually, when the serialized object contains other objects, you can't just dump it to a file and reconstitute a valid object subsequently. In our example, the enclosing object contains a "std::string member." A shallow copy would archive transient "std::string" members whose values are transient, meaning that they may change every time you run the program. Worse yet, because "std::string" doesn't actually contain a char array but a pointer, it would be impossible to reconstitute the original string if we used shallow copying. To overcome this problem we didn't serialize the string object. Instead, we archived its characters and length. In general, pointers, arrays and handles should be treated similarly.

0

użyj np. Boost::Serialize

1 użytkowników online, w tym zalogowanych: 0, gości: 1