Boost动态序列化所有派生类型



是否绝对有必要对虚拟基类的所有派生类型调用BOOST_CLASS_EXPORT()register_type() ?有没有办法只指定基类?

下面是一些示例代码(我使用boost 1.59):

    #include <iostream>
    #include <string>
    #include <memory>
    #include <boost/serialization/serialization.hpp>
    #include <boost/serialization/shared_ptr.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    //#include <boost/make_shared.hpp>
    #include <boost/serialization/export.hpp>
    #include <boost/serialization/base_object.hpp>
    class Parent {
      public:
        int test_val = 1234234;
        int p() { return 13294; }
            virtual void testing() = 0;
        int get_test_val() {
            std::cout << __PRETTY_FUNCTION__ << ":" << test_val << "n";
            return test_val;
        }
        template <class Archive> void serialize(Archive &ar, unsigned) {
            ar & test_val;
        }
    };
    //BOOST_SERIALIZATION_ASSUME_ABSTRACT(Parent)
    class RefMem : public Parent {
      public:
        RefMem() {
            test_val = 12342;
            std::cout << __PRETTY_FUNCTION__ << ":" << test_val << "n";
        }   
            void testing() {
                    std::cout << "TEST" << std::endl;
            }
            template<class Archive> void serialize(Archive &ar, unsigned) {
                    ar & boost::serialization::base_object<Parent>(*this);
            }
    };

class RefMem2 : public Parent {
        public:
                RefMem2() {
                        test_val  = 9823;
                        std::cout << __PRETTY_FUNCTION__ << ":" << test_val << "n";
                }
                void testing() {
                        std::cout << "TEST2" << std::endl;
                }
                 template<class Archive> void serialize(Archive &ar, unsigned) {
                        ar & boost::serialization::base_object<Parent>(*this);
                }
};
    using ParentRef = std::shared_ptr<Parent>;
    class Test {
      public:  
        int t_ = 0;
        ParentRef parent_;
        Test(int t = 0, ParentRef parent = std::make_shared<RefMem>()) : t_(t), parent_(parent) { }
        template <class Archive> void serialize(Archive &ar, const unsigned int file_version) {
            ar & t_ & parent_;
        }
    };
    //BOOST_CLASS_EXPORT(RefMem)
    #include <sstream>
    int main() {
        ParentRef the_instance = std::make_shared<RefMem>();
        Test test = Test(50, the_instance);
        std::cout << "t_: " << test.t_ << "n";
        std::cout << "Test val: " << test.parent_->get_test_val() << "n";
        std::ostringstream oss;
        {
            boost::archive::text_oarchive oa(oss);
            oa.register_type<RefMem>();
            oa.register_type<RefMem2>();
            oa << the_instance << test; // NOTE SERIALIZE test AS-IF A POINTER
        }
        {
            ParentRef the_cloned_instance;
            Test cloned;
            std::istringstream iss(oss.str());
            {
                boost::archive::text_iarchive ia(iss);
                    ia.register_type<RefMem>();
                    ia.register_type<RefMem2>();
                ia >> the_cloned_instance >> cloned;
            }
            std::cout << "t_: " << cloned.t_ << "n";
            std::cout << "Test val: " << cloned.parent_->get_test_val() << "n";
            std::cout << "Are Parent objects aliasing: " << std::boolalpha <<
                (cloned.parent_ == the_cloned_instance) << "n";
        }
    }

是必须的。

你已经看到了机制。这个宏只是一种自动化register_type舞蹈的方法,用于在宏扩展时已知的存档类型。

在这个实例中,您可以在Test序列化方法中列出类型,这将是"及时的"—只要您在此之前不反序列化Parent多态实例。

class Test {
public:
    int t_ = 0;
    ParentRef parent_;
    Test(int t = 0, ParentRef parent = std::make_shared<RefMem1>()) : t_(t), parent_(parent) {}
    template <class Archive> void serialize(Archive &ar, unsigned) {
        ar.template register_type<RefMem1>();
        ar.template register_type<RefMem2>();
        ar & t_ & parent_; 
    }
};

如果你改变归档顺序:

    oa << test << the_instance;
    // ...
    ia >> cloned >> the_cloned_instance;

生活在Coliru

最新更新