Boost serialization with pointers and non-default constructor

后端 未结 1 2075
半阙折子戏
半阙折子戏 2020-12-17 01:31

How would you serialize/deserialize this class using boost::serialization?

#include 

struct Foo {
    struct Bar {
        std::vector

        
1条回答
  •  春和景丽
    2020-12-17 02:27

    There is a section in the documentation that describes how to (de)serialize classes with non-default constructors. See here.

    Basically, you must implement two functions called save_construct_data and load_construct_data in the namespace boost::serialization to write out and read in the data used to construct instances of your class. You can then call a non-default constructor of Foo from the load_construct_data function with the parameters necessary to reconstruct a Foo object.


    Here is a working example based on your updated code:

    Note that I've used shared_ptr's to clarify that the data member serialized by Foo and Bar are referencing the same thing.

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    
    struct Foo {
        struct Bar {
            boost::shared_ptr< std::vector > data; // Must point to Foo::data
    
            Bar( boost::shared_ptr< std::vector > d ) : data(d) { }
    
            template
            void serialize(Archive & ar, const unsigned int version)
            {
              // ** note that this is empty **
            }
        };
    
        boost::shared_ptr< std::vector > data;
        std::vector elements;
    
        Foo() : data( new std::vector() ) {
            std::cerr << "Running default constructor" << std::endl;
            data->push_back(1);
            data->push_back(2);
            data->push_back(3);
            data->push_back(4);
            data->push_back(5);
            elements.push_back( Bar( data ) );
            elements.push_back( Bar( data ) );
            elements.push_back( Bar( data ) );
        }
    
        template
        void serialize(Archive & ar, const unsigned int version)
        {
          // ** note that this is empty **
        }
    
        Foo(
          boost::shared_ptr< std::vector > const & data_,
          std::vector const & elements_ ) : data( data_ ), elements( elements_ )
        {
            std::cout << "cheap construction" << std::endl;
        }
    };
    
    namespace boost { namespace serialization {
    
    template
    inline void save_construct_data(
        Archive & ar, const Foo * foo, const unsigned int file_version
    ){
        ar << foo->data << foo->elements;
    }
    
    template
    inline void load_construct_data(
        Archive & ar, Foo * foo, const unsigned int file_version
    ){
        boost::shared_ptr< std::vector > data;
        std::vector elements;
    
        ar >> data >> elements;
    
        ::new(foo)Foo(data, elements);
    }
    
    template
    inline void save_construct_data(
        Archive & ar, const Foo::Bar * bar, const unsigned int file_version
    ){
        ar << bar->data;
    }
    
    template
    inline void load_construct_data(
        Archive & ar, Foo::Bar * bar, const unsigned int file_version
    ){
        boost::shared_ptr< std::vector > data;
    
        ar >> data;
    
        ::new(bar)Foo::Bar(data);
    }
    
    }}
    
    int main()
    {
      std::stringstream ss;
    
      {
        boost::scoped_ptr< Foo > foo( new Foo() );
    
        std::cout << "size before serialization is: " << foo->data->size() << std::endl;
    
        boost::archive::text_oarchive oa(ss);
        oa << foo;
      }
    
      {
        boost::scoped_ptr< Foo > foo;
    
        boost::archive::text_iarchive is(ss);
        is >> foo;
    
        std::cout << "size after deserialization is: " << foo->data->size() << std::endl;
      }
    
      return 0;
    }
    

    0 讨论(0)
提交回复
热议问题