I have a C++ class defined as A a;
which I would like to serialize. The simplest way to do this (when it works) is
write(fd, reinterpret_cast<uint8_t*>(&a), sizeof(a));
and to read it back using:
read(fd, reinterpret_cast<uint8_t*>(&a), sizeof(a));
I know that this will work if std::is_pod<A>::value
is true types but what is the most relaxed set of type traits A
must exibit for this to to work?
Just for completeness, this is for persistence between running instances of the application, there is no need for the file to be readable by another program or on another platform.
Serialization is the process of writing or reading an object to or from a persistent storage medium such as a disk file. Serialization is ideal for situations where it is desired to maintain the state of structured data (such as C++ classes or structures) during or after execution of a program.
use std::string or std::vector<byte> to hold the serialized data (and dispose of that #define PACKETSIZE altogether) and use it as a return value of the serialize function instead of the output parameter (or if you insist change the parameter to char(&data)[PACKETSIZE] ). This is a good simple implementation, true.
Serializing whole objects To unserialize an object, it should have a constructor that takes byte stream. It can be an istream but in the simplest case it can be just a reference uint8_t pointer. The constructor reads the bytes it wants from the stream and sets up the fields in the object.
Object Serialization with the Boost C++ Library Note that, for each class to be serialized, there is a template function that saves the whole class definition. The classes should be restored in the same sequence they were stored. This is particularly important if different objects are stored in the same file.
Writing the bitwise image of an object into a stream and restoring it correctly by reading from that stream is exactly the same as the object behaving correctly under memcpy
. And for that, there's the specific property of begin trivially copyable. So the trait you want to use is std::is_trivially_copyable<A>
.
Unrelated side note: Your code could theoretically have Undefined Behaviour. That is because C++ only allows aliasing through types char
and unsigned char
, and there's no guarantee that std::uint8_t
is an alias for one of those. You'd better off using unsigned char
explicitly:
write(fd, reinterpret_cast<unsigned char*>(&a), sizeof(a));
What you are looking for is is_trivially_copyable
, as per agnew's answer. However, this does not mean trivially serializable because of
Furthermore, you will run into problems with versioning, and the meaning of data may be different on different execution machines.
That's why I would recommend to introduce a custom trait,is_doron_serializabe
, and have it default to false
for types not explicitely marked as compatible.
(What you are planning may be OK in some circumstances.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With