Increase serialization of a derived object does not cause derivative serialization ()

I read a lot of similar questions, but could not find an answer. I am using Visual Studio 2010 and increasing 1.47.

Here is the code, it is complete and compiled:

#include "stdafx.h" #include <string> #include <sstream> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <boost/serialization/export.hpp> using namespace std; class BaseObject { public: BaseObject(void) { }; virtual ~BaseObject(void) { }; template<class Archive> void serialize(Archive &ar, const unsigned int version) { /* nothing happens here */ }; }; class DerivedObject : public BaseObject { public: string text; public: DerivedObject(void) { }; ~DerivedObject(void) { }; template<class Archive> void serialize(Archive &ar, const unsigned int version) { ar & text; }; }; BOOST_CLASS_EXPORT(DerivedObject) int _tmain(int argc, _TCHAR* argv[]) { DerivedObject der; der.text = "Testing!"; std::ostringstream os; boost::archive::text_oarchive oa(os); oa.register_type<DerivedObject>(); // I made a DerivedObject, but I'm casting it to a BaseObject // as the serialization code should not have to know what type it is BaseObject *base = &der; // now serialize it oa << *base; printf("serialized: %s\r\n",os.str().c_str()); return (0); } 

You can see it very simple, and I added the magic of BOOST_CLASS_EXPORT and oa.register_type, which was to make sure DerivdObject :: serialize () was called, although this was not a virtual method ... but still only serialized () to BaseObject. Perhaps a problem with Visual C ++? Please advice?

+6
source share
3 answers

As described in the enhancement documentation for serialization , you need to tell the derived class to call the serialization code of the base class. Just write your serialization method for the derived class as follows:

  template<class Archive> void serialize(Archive &ar, const unsigned int version) { ar & boost::serialization::base_object<BaseObject>(*this); ar & text; }; 
+2
source

I have not tried this in a debugger or anything else, but it looks like it might be a slicing case. Perhaps you could find out by changing your code to serialization by pointer or by reference instead of value, for example ...

 BaseObject *base = &der; oa << base; // Serialize a pointer 

... or...

 BaseObject& base = der; oa << base; // Serialize a reference 
0
source

This is not strictly an answer, just a workaround.

In the base class add:

 virtual void StreamToArchive(boost::archive::text_oarchive &oa) = 0; 

then define a STREAMTOARCHIVE macro and place it in each of the derived classes.

 #define STREAMTOARCHIVE void StreamToArchive(boost::archive::text_oarchive &oa) { oa << *this; } 

Then basically replace

 oa << base; 

from

 base.StreamToArchive(oa); 

Yes, I know, this is ugly, but .. it works well, and I just have to put this STREAMTOARCHIVE macro into derived classes ... I can live with it ...

But then ... disassemble it back into the object, now that's another matter ...

Edited: changed 'this' to '* this'

0
source

Source: https://habr.com/ru/post/910784/


All Articles