1

I would like to know what happens when I write:

object.write((char*)&class_object, sizeof(class_object));
// or
object.read((char*)&class_object, sizeof(class_object));

From what I read so far, the class_object is converted to a pointer. But I don't know how it manages to convert data carried by the object into binary. What does the binary actually represent?

I am a beginner.

EDIT

Could you please explain what really happens when we write the above piece of code? I mean, what actually happens when we write (char*)*S, say where S is the object of a class that I have declared?

Karthik
  • 113
  • 1
  • 8

2 Answers2

1

In practice, your code won't work and is likely to yield undefined behavior, at least when your class or struct is not a POD (plain old data) and contains pointers or virtual functions (so has some vtable).

The binary file would contain the bit representation of your object, and this is not portable to another computer, or even to another process running the same program (notably because of ASLR) unless your object is a POD.

See also this answer to a very similar question.

You probably want some serialization. Since disks and file accesses are a lot slower (many dozen of thousands slower) than the CPU, it is often wise to use some more portable data representation. Practically speaking, you should consider some textual representation like e.g. JSON, XML, YAML etc.... Libraries such as jsoncpp are really easy to use, and you'll need to code something to transform your object into some JSON, and to create some object from a JSON.

Remember also that data is often more costly and more precious than code. The point is that you often want some old data (written by a previous version of your program) to be read by a newer version of your program. And that might not be trivial (e.g. if you have added or changed the type of some field in your class).

You could also read about dynamic software updating. It is an interesting research subject. Be aware of databases.

Read also about parsing techniques, notably about recursive descent parsers. They are relevant.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
1

Imagine it this way, the class instance is just some memory chunk resting in your RAM, if you convert your class to a char pointer:

SomeClass someClassInstance;
char* data = reinterpret_cast<char*>(&someClassInstance);

It will point to the same data in your memory but it will be treated as a byte array in your program.

If you convert it back:

SomeClass* instance = reinterpret_cast<SomeClass*>(data);

It will be treated as the class again.

So in order to write your class to a file and later reconstruct it, you can just write the data to some file which will be sizeof(SomeClass) in size and later read the file and convert the raw bytes to the class instance.

However, keep in mind that you can only do this if your class is POD (Plain Old Data)!

ProXicT
  • 1,903
  • 3
  • 22
  • 46
  • By `data` I mean the pointer to the raw bytes. Usually it's the raw bytes which are written to files. The `data` will point to the memory where the class instance resides, to write it to file, you can do something like `ofstream.write(data, sizeof(SomeClass));` – ProXicT Oct 26 '17 at 08:14
  • So we technically use pointers that moves across the memory locations are write them in binary for us? – Karthik Oct 26 '17 at 08:21
  • I'm affraid I don't understand your question, pointers just point to memory addresses and on each address there is one byte. The pointer `data` points to the start of the raw data of your class instance. If you add 1 to the pointer `data`, it will point to the second byte. Pointer is really just a number, you can add to it and subtract from it. If you dereference the pointer, it will give you the value it points to. This way the `write` function is able to write all the raw data to a file. It will just increment the pointer `n` times where `n` is your `sizeof(SomeClass)` to write all data. – ProXicT Oct 26 '17 at 10:21
  • Glad it helped ;-) – ProXicT Oct 26 '17 at 11:12