Is it absolutely necessary to call BOOST_CLASS_EXPORT()
or register_type()
for all derived types of a virtual base class? Is there any way to just specify the base class?
Here's some sample code (I'm using 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";
}
}