Search code examples
c++classstructrandom-accessrandomaccessfile

Best practice in storing class data in random access files


In C, data is typically organised in a struct data type. This is very convenient to save in a random access file, because you can just skip to the record you want using sizeof on the structure.

What is not clear to me what is the best approach to do this in C++, where you have a class with the data (together with some member functions which of course do not need to be persisted). Storing the class directly seems to be wrong, because of course this will include pointers to functions and that kind of stuff which is garbage once persisted to file.

Another approach I could think of is changing the member data inside the class, that needs to be persisted, to a struct, and change the accessor functions to look into the inner data structure. It seems to be a bit too intertwined but seems to be the only logical way to avoid replicating each field twice (once in a separate struct and once in the class).

This breaks down of course the moment you have inheritance, and the derived class adds new fields. Although this is hardly a problem specific to C++ and random access files, and its faced in many other Object Persistence approaches (including popular ORM packages in other programming languages) with different possible strategies even when saving to a database table for instance.

Is there any 'defacto standard' approach people typically use in C++ to persist class data in files? Without having to replicate things all over the place?


Solution

  • Short answer: it depends

    Medium answer: it depends just the same in C struct can be directly serializable or not.

    Long answer: If a class A is just Plain Old Data, it will be serializable as you could do with a C struct, that is binary copy and load sizeof(A) bytes. A class is a POD object if it contains only primitive type members or arrays of them, and/or subobjects that are POD themselves. It can have methods or static methods, but no virtual methods (not even a virtual destructor).

    For example char arrays are acceptable, but no pointer, no string, no reference, and (genererally speaking) no object from the standard library (notably no std::string).

    Of course, as it directly stores and load binary data representations, it will definitively not be portable across different architectures, but can be used to locally save state.