6

I am looking at Boost.Serialization for the first time, and I cannot find a clear assessment (or instructions) regarding the serialization of a virtual diamond inheritance structure.

Consider the following class hierarchy:

class A { int a; }

class B1 : public virtual A { int b1; }

class B2 : public virtual A { int b2; }

class B3 : public virtual A { int b3; }

class C12 : public virtual B1, public virtual B2 { int c12; }

class C13 : public virtual B1, public virtual B3 { int c13; }

class C23 : public virtual B2, public virtual B3 { int c23; }

class D123 : public virtual C12, public virtual C13, public virtual C23 { int d123; }

What is the proper (hopefully, simple) way to implement serialization within all of these classes using Boost.Serialization?

Note: There are no pointer or reference class members that need to be serialized. Also note: I am happy to use dynamic_cast<> to assure that any pointers or references to any classes in this hierarchy are of the desired, derived-most type: I am simply concerned about how to properly, and cleanly, guarantee that all BASE-class data members are properly serialized, and deserialized, along with the current class being serialized.

Dan Nissenbaum
  • 13,558
  • 21
  • 105
  • 181
  • You may have a bit of trouble using serialization because it is a template class, if you are using virtual methods: http://stackoverflow.com/questions/10490245/virtual-functions-and-template-clash – Fantastic Mr Fox Nov 19 '12 at 04:30
  • @Ben I believe the issue in the linked question pertains to *abstract* base classes (i.e., base classes with *pure* virtual functions) only, because such classes cannot be instantiated, and hence it is impossible to instantiate the required `serialize()` function within such a class. I do not believe that virtual functions impact Boost.Serialization otherwise - in fact, it's specifically data, and data only, that is serialized, so I would think that the presence of virtual functions is, essentially, irrelevant to Boost.Serialization except indirectly, as in the example in the link. – Dan Nissenbaum Nov 19 '12 at 04:48
  • @Ben The following link seems to present a well-supported way to use Boost.Serialization with abstract base classes: http://stackoverflow.com/questions/1332602/how-to-serialize-derived-template-classes-with-boost-serialize – Dan Nissenbaum Nov 19 '12 at 04:58

1 Answers1

2

When serializing objects with virtual base classes, you will have to explicitly enable object tracking for the virutal base classes:

BOOST_CLASS_TRACKING(virtual_base, boost::serialization::track_always)

From object tracking:

In a diamond heritance structure with a virtual base class, object tracking will prevent redundant save/load invocations. So here is one case where it might be convenient to override the default tracking trait. (Note: in a future version the default will be reimplemented to automatically track classes used as virtual bases).

As for de/serializing base classes, use:

archive & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);

before serializing member variables (archive & BOOST_SERIALIZATION_NVP(variable)) with intrusive serialization. For non-intrusive serialization it's up to you to deal with all the member variables involved.

All this is based on the assumption that you de/serialize a non-polymorphic class (with virtual base classes) through a pointer or reference of the most derived type.

Anonymous Coward
  • 6,186
  • 1
  • 23
  • 29
  • Does that mean that if I have a pointer to an object where the pointer type is that of a class in the middle of a multiple-level "diamond" hierarchy, but the object is itself of a further derived class - but the class corresponding to this pointer type *IS* a polymorphic type (i.e., it has at least one virtual function defined and therefore has a vtable) that Boost.Serialization will properly serialize the object INCLUDING all the way down to its most derived-class members (i.e. even though the pointer points to a base class type)? – Dan Nissenbaum Nov 19 '12 at 06:53
  • @DanNissenbaum If you have a polymorphic hierarchy you need to either [export or register](http://www.boost.org/doc/libs/1_52_0/libs/serialization/doc/serialization.html#derivedpointers) the class for serialization through a pointer to a less derived type. Also you have to deserialize to the same type you serialize (different types are not tested in the boost::serialization unit tests). – Anonymous Coward Nov 19 '12 at 07:17
  • @AnonymousCoward Is `BOOST_SERIALIZATION_BASE_OBJECT_NVP` preferred over `boost::serialization::base_object(*this);` ? – David Doria Mar 01 '16 at 22:18