是否绝对有必要对虚拟基类的所有派生类型调用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