'Can I serialize a class by casting it to a char*
In C++, can I cast a class or some data to a void*
, then to a char*
to serialize it? If so, how would I de-serialize?
I don't really care about portability.
class t{
public:
uint8_t data[32][32][32]
}
t temp;
temp.data = something;
char* serialized = (char*)(void*)&temp;//????
Solution 1:[1]
This is not the way to go.
In which conditions could it work?
In the best case of a type that contains no pointer and that is in addition trivially copyable type, you could indeed write the bytes at the memory address of the object to a file, and reload the data safely later.
But casting is not sufficient: casting to char*
allows you to write or copy the raw data somewhere. But only if you also know the size of the object. The pointer alone does not carry this length information.
For deserializing with success, you'd need not only to read the size of the data and its raw content. But you would need also to know the class, to create an object before uploading its raw data. This implies that you also write an information about the object type, and that your deserialization function can cope with this information.
Why will it fail in the general case ?
Of course, this very basic serialization/deserialization approach will fail as soon as you'll have a more elaborate class. For example:
- If you have a non-trivial constructor or an assignment operator, this deserialisation tactic cannot guarantee that your data structures stay consistent. For example, if the constructor or assignement operator would maintain some kind of static object count, it would be out of sync after the deserialization.
- As soon as you have a pointer or non-trivially copyable member object, you can bet that all the data that you need is not necessarily contiguous. So your writing of the object will only write a part of the data needed. In addition, pointer values are only valid in the current process. If you read it in another process (orther programme, or the same programme exectued on another day), the pointer value is useless.
In other words, in most of the cases, your programme will be UB.
How to do it the right way ?
It's not difficult to do serialization properly. First there are plenty of libraries that do a big part of the job for you.
But yourself can easily write it yourself: you just need to have a save()
function in every serializable class: the objects would serialize themseves, since they know best what is to be written! Each class would also have a static factory with a load()
function, that is able to create a new object and populate it with the data.
Solution 2:[2]
If the class is POD (Plain Old Data), then maybe. Usually it is not, so you have to serialize manually. For example, any class that contains pointers directly or indirectly (say, by including objects that contain pointers such as std::string) cannot be automatically serialized to an array. You also have different memory alignments between different systems.
Related: What are POD types in C++?
Solution 3:[3]
"can i serialize a class by casting it to a char*" - In general; No.
You cannot serialise/deserialize by casting stuff. A cast doesn't convert anything it just changes how the compiler views/interprets data.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Christophe |
Solution 2 | |
Solution 3 | Jesper Juhl |