How do you serialize an object in C++?


I have a small hierarchy of objects that I need to serialize and transmit via a socket connection. I need to both serialize the object, then deserialize it based on what type it is. Is there an easy way to do this in C++ (as there is in Java)?

Are there any C++ serialization online code samples or tutorials?

EDIT: Just to be clear, I'm looking for methods on converting an object into an array of bytes, then back into an object. I can handle the socket transmission.

5/10/2011 12:14:14 PM

Accepted Answer

Talking about serialization, the boost serialization API comes to my mind. As for transmitting the serialized data over the net, I'd either use Berkeley sockets or the asio library.

If you want to serialize your objects to a byte array, you can use the boost serializer in the following way (taken from the tutorial site):

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
class gps_position
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
        ar & degrees;
        ar & minutes;
        ar & seconds;
    int degrees;
    int minutes;
    float seconds;

    gps_position(int d, int m, float s) :
    degrees(d), minutes(m), seconds(s)

Actual serialization is then pretty easy:

#include <fstream>
std::ofstream ofs("filename.dat", std::ios::binary);

    // create class instance
    const gps_position g(35, 59, 24.567f);

    // save data to archive
        boost::archive::binary_oarchive oa(ofs);
        // write class instance to archive
        oa << g;
        // archive and stream closed when destructors are called

Deserialization works in an analogous manner.

There are also mechanisms which let you handle serialization of pointers (complex data structures like tress etc are no problem), derived classes and you can choose between binary and text serialization. Besides all STL containers are supported out of the box.

7/28/2012 12:43:53 AM

In some cases, when dealing with simple types, you can do:

object o;
socket.write(&o, sizeof(o));

That's ok as a proof-of-concept or first-draft, so other members of your team can keep working on other parts.

But sooner or later, usually sooner, this will get you hurt!

You run into issues with:

  • Virtual pointer tables will be corrupted.
  • Pointers (to data/members/functions) will be corrupted.
  • Differences in padding/alignment on different machines.
  • Big/Little-Endian byte ordering issues.
  • Variations in the implementation of float/double.

(Plus you need to know what you are unpacking into on the receiving side.)

You can improve upon this by developing your own marshalling/unmarshalling methods for every class. (Ideally virtual, so they can be extended in subclasses.) A few simple macros will let you to write out different basic types quite quickly in a big/little-endian-neutral order.

But that sort of grunt work is much better, and more easily, handled via boost's serialization library.

Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow