I came across a lesson where we used a user-defined type called "Person" that stores a person's name in a char array and age as an integer. The lesson was on writing and reading binary files. The main program looks like this:
int main()
{
Person anil("anil",24); //initialize with name and age
fstream file("person.bin", ios::binary | ios::in | ios::out | ios::trunc);
if (!file.is_open())
cout << "Error while opening file.";
else
{
file.write((char*)&anil, sizeof(Person));
file.seekg(0); // go back to beginning
Person anjali; //declare new person object
//first argument is memory block, second argument is byte size
file.read((char*)&anjali, sizeof(Person));
anil.whoAreYou(); //outputs the name and age
anjali.whoAreYou();
}
return 0;
}
I don't understand what is happening with these lines:
file.write((char*)&anil, sizeof(Person));
file.read((char*)&anjali, sizeof(Person));
I understand the write and read functions of fstream require the memory_block as the first argument...can someone explain what exactly is happening when the reference to the user-defined type is cast to a char * ?
In C/C++, char *
is often used as a generic type of data since it always points to 1 byte. The casting code (char*)&anil
in your code gets the pointer to anil
with &
and casts that to a pointer to char
s. It writes that sequence of char
s to the file and then reads it back into an the memory for anjali
.
This does an exact memory copy, which causes issues if you have a pointer to somewhere else in that memory as that pointer will nearly never be valid when loading the object back. This may serve as a bit of an example, but real-world serialization is quite tricky and is often best left to some sort of serialization library. Hand serialization is possible, but that should only be done very carefully in a library or such.
If you wish to do this hand serialization, you need to determine a format for your serialization and write the base values to the file. You'll also need to determine if you actually want binary serialization or if text-based serialization would be better suited. In most cases, writing an object to a file format like JSON is a bit easier and also has the advantage of being portable between languages and human readable.