Boost Serialization for inherited objects

Preface:

When chatting with a colleague yesterday, I referenced a blog post I never actually wrote. So to remedy that here we go, how to use boost in the case of inheritance.

How To:

Inheritance in C++ is very important, a long with classes and templates I would say the most important triplet (of course inheritance cant exist without classes). As I mentioned in a previous blog post I found a new love of boost serialization allowing me to easily be able to save out my objects in binary,text or xml, but there is a spanner in the works when it comes to inheritance, this is due to the serializer not being able to know it has a parent or even what that parent is.This is actually solved with a small amount additional of code but is critical to put in or your objects wont behave in the expected way.

1 class MyParent { 2 public: 3 MyParent() {}; 4 virtual ~MyParent() {}; 5 int getID(){ return ID; } ; 6 int setID(int num){ ID = num; } ; 7 8 private: 9 int ID; 10 friend class boost::serialization::access; 11 template<class Archive> void serialize(Archive& ar, 12 const unsigned int version) { 13 ar & BOOST_SERIALIZATION_NVP(ID); 14 } 15 }; 16 17 class MyChild : public MyParent { 18 public: 19 MyChild() {}; 20 ~MyChild() {}; 21 22 private: 23 friend class boost::serialization::access; 24 template<class Archive> void serialize(Archive& ar, 25 const unsigned int version) { 26 } 27 };

So we serialize out the child class and what do we get? Well actually it is very clean elegant empty file. Not what was intended, but with a small change to tell the compiler of the classes parent we are able to serialize out child classes and parents without a problem

1 ar & boost::serialization::make_nvp("MyParent", 2 boost::serialization::base_object<MyParent>(*this))

As you hopefully can see this tells the compiler what the object parent is and provides a reference to it so therefore you can serialize that out. Of course you can put this line at the beginning or end depending on how you want to structure your outputs, but to my brain coming first makes sense.

The final solution being:

1 class MyParent { 2 public: 3 MyParent() {}; 4 virtual ~MyParent() {}; 5 int getID(){ return ID; } ; 6 int setID(int num){ ID = num; } ; 7 8 private: 9 int ID; 10 friend class boost::serialization::access; 11 template<class Archive> void serialize(Archive& ar, 12 const unsigned int version) { 13 ar & BOOST_SERIALIZATION_NVP(ID); 14 15 16 } 17 }; 18 19 class MyChild : public MyParent { 20 public: 21 MyChild() {}; 22 ~MyChild() {}; 23 24 private: 25 friend class boost::serialization::access; 26 template<class Archive> void serialize(Archive& ar, 27 const unsigned int version) { 28 ar & boost::serialization::make_nvp("MyParent", 29 boost::serialization::base_object<MyParent>(*this)) 30 } 31 };
Saturday, November 17, 2012 11:34:00 AM Categories: C++ HowTo Programming
Stuart James