Possible Duplicate:
Boost Serialization using polymorphic archives
I am trying to serialize my classes using a base pointer to a derived class, but that only serializes the base class.
I just read http://www.boost.org/doc/libs/1_32_0/libs/serialization/doc/special.html#registration, but both the export macro and the register function didn't seem to change anything.
Consider the following, very basic, class hierarchy:
#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
class A
{
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive& ar, const unsigned int version)
{
std::cout << "A!\n";
}
};
class B : public A
{
private:
friend class boost::serialization::access;
template <typename Archive>
void serialize(Archive& ar, const unsigned int version)
{
ar & boost::serialization::base_object<A>(*this);
std::cout << "B!\n";
}
};
int main()
{
std::ofstream of("mybin.bin");
boost::archive::binary_oarchive oa(of);
A* b = new B();
oa << b;
delete b;
return 0;
}
Output will be:
A!
Clearly, the output I'm looking for is A! B!. Is there any way this can be achieved ?
EDIT: Ok, after looking at the related entry in the comments, here is what is going on.
There was 3 things to change:
It works with a standard binary_oarchive, as well as the polymorphic_binary_oarchive.
EDIT2: When I have let's say b.cpp(.h) and main.cpp, the BOOST_CLASS_EXPORT results in duplicate symbols:
duplicate symbol boost::archive::detail::extra_detail::init_guid::g
I must admit I am not familiar with this boost package, but I copied and compiled the code, which produced the same result as the OP mentioned
Realizing that we are using polymorphism, I added a public: virtual ~A(){}; in class A. Also, oa.register_type<B>(); is added in main according to the document, and output became:
A!
B!
According to the specification, a class is a polymorphic class only when declares or
inherits a virtual function. For non-polymorphic classed, maybe polymorphism just does not work.
EDIT:
Putting the BOOST_CLASS_EXPORT(B); in B.cpp instead of B.h seems to solve this problem of redefinition.
EDIT:
Checked the expansion result of BOOST_CLASS_EXPORT(B) (reformatted):
namespace boost {
namespace serialization {
template<> struct guid_defined<B> : boost::mpl::true_ {};
template<> inline const char * guid<B>(){ return "B"; }
}
}
namespace boost {
namespace archive {
namespace detail {
namespace { // NOTE
template<> struct init_guid< B > {
static guid_initializer< B > const & g;
};
guid_initializer< B > const & init_guid< B >::g = ::boost::serialization::singleton< guid_initializer< B > >::get_mutable_instance().export_guid();
}
}
}
}
And for the line marked with NOTE: for boost 1.42 used an anonymous namespace is used, which will be no problem if it is put into multiple cpp files or put into a header file (tested in ubuntu with g++, using the boost package come along with Ubuntu). However, in boost 1.48, namespace extra_detail is used, which would cause problems when put into multiple cpp files (tested in windows with VS2010, using boost downloaded from homepage).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With