c++ - Serializing a derived class from an interface -


new: can use this, access.hpp?

template<class archive, class t> inline void serialize_adl(archive &, t &, const unsigned int); 

this suggests can define different serialize takes object parameter.

thus code change below work?

i think question how add serialize method on interface class, invoke serialize method on derived sub-class.

class interface { public:     virtual void avirtual() = 0; private:     friend class boost::serialization::access;     template<class archive, class t>     void serialize_adl(archive & ar, t & object, const unsigned int version)     {        // work?????        ar & object;     } };  template<class t> class derived : interface { public:    derived(t in) : m_data(in) {}    virtual void avirtual() { // } private:     t m_data;     friend class boost::serialization::access;     template<class archive>     void serialize(archive & ar, const unsigned int version)     {        ar & m_data;     } }; 

i following error compiler:

error c2039: 'serialize' : not member of 'interface' 

which unusual because object inside smart pointer, should know type is:

std::unique_ptr<interface> object = std::unique_ptr<interface>(new derived<int>(5)); 

and when try serialise:

archive >> *object; 

thus error.

there's 2 issues @ play here:

  1. you serializing template class. not problem , yes can intrusively (member serialize) or non-intrusively (free function serialize via adl). documentation (serializing templates) states implementation of shared_ptr<t> serialization example of non-intrusive variant here:


  2. you serializing base/derived classes through polymorphic pointer. serialization part nothing special (you can register_type or should fine using base_object<interface>(this) inside derived's serialize function.

    on deserialization side of things, however, need anticipate full list of possible concrete instance types serialized through polymorphic pointer. boost_export_class macro easiest way achieve this. have list concrete instances of template wish support, though:

    boost_class_export(derived<std::string>) boost_class_export(derived<double>) boost_class_export(derived<int>) // include subtypes can expect in input archive 

    or

    boost_class_export_guid(derived<std::string>, "4ef5a3ff-168a-4242-846b-4886f48424b5") boost_class_export_guid(derived<double>,      "d0ed9de6-584f-476d-9898-8234bcb4efdb") boost_class_export_guid(derived<int>,         "505538f0-2dd1-43bd-92a2-506ed9659bbe") // include subtypes can expect in input archive 

the complexity of situation - , confusion - arises fact serializing derived class template through polymorphic pointer. @ same time. conceptually both tackled.

slightly unrelated,

  • yes, can use free function serialize, see 3rd alternative version below. gains little though, , requires m_data publicly accessible.
  • do not use serialize_adl implementation detail

here 3 samples integrates everything:

  1. live on coliru - raw interface*

  2. live on coliru - same shared_ptr<interface>

  3. live on coliru - same non-intrusive serialize function

listing first sample

#include <boost/serialization/serialization.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/export.hpp> #include <boost/archive/text_oarchive.hpp> #include <boost/archive/text_iarchive.hpp> #include <sstream>  class interface {     public:         virtual void avirtual() = 0;         virtual ~interface() {}     private:         friend class boost::serialization::access;         template<class archive> void serialize(archive&, unsigned) { } };  boost_serialization_assume_abstract(interface)  template<class t> class derived : public interface {     public:         derived(t in = 0) : m_data(in) {}         virtual void avirtual() { /*do something*/ }         t const& getdata() const { return m_data; }     private:         t m_data;         friend class boost::serialization::access;         template<class archive>             void serialize(archive& ar, unsigned)             {                 ar & boost::serialization::base_object<interface>(*this);                 //// alternatively, if don't want make abstract base serializable:                 // boost::serialization::void_cast_register<derived, interface>();                  ar & m_data;             } };  boost_class_export(derived<std::string>) boost_class_export(derived<double>) boost_class_export(derived<int>) // include subtypes can expect in input archive  int main() {     std::stringstream ss;      {         boost::archive::text_oarchive oa(ss);          interface* o = new derived<int>(42);         oa << o;          delete o;     }      std::cout << "serialized: '" << ss.str() << "'\n";      {         boost::archive::text_iarchive ia(ss);          interface* o = nullptr;         ia >> o;          if (auto p = dynamic_cast<derived<int>*>(o))             std::cout << "deserialized derived<int> data: " << p->getdata() << "\n";          delete o;     } } 

sample output:

serialized: '22 serialization::archive 11 0 1 1 12 derived<int> 1 0 0 42 ' deserialized derived<int> data: 42 

Comments

Popular posts from this blog

plot - Remove Objects from Legend When You Have Also Used Fit, Matlab -

java - Why does my date parsing return a weird date? -

Need help in packaging app using TideSDK on Windows -