I am wondering about this. I have a C++ program with a number of data structs which derive from a common root and I need to serialize them using Boost. Each one has an inline member function to accept a visitor (so I can visit the structure without a "switch" statement).
The objects look like this:
In the .h file:
// Graphic component.
struct GraphicComponent : public Component {
... data members ...
void accept(ComponentVisitor &vis) { vis.visitGraphicComponent(*this); }
private:
// Serialization routine.
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &a, const unsigned int v);
};
BOOST_CLASS_EXPORT_KEY(GraphicComponent)
// Position component.
struct PositionComponent : public Component {
... data members ...
void accept(ComponentVisitor &vis) { vis.visitPositionComponent(*this); }
private:
// Serialization routine.
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive &a, const unsigned int v);
};
BOOST_CLASS_EXPORT_KEY(PositionComponent)
...
In the .cpp file, I declare the "serialize" routines:
BOOST_CLASS_EXPORT_IMPLEMENT(GraphicComponent)
BOOST_CLASS_EXPORT_IMPLEMENT(PositionComponent)
...
template<class Archive>
void GraphicComponent::serialize(Archive &a, const unsigned int v)
{
a & boost::serialization::base_object<Component>(*this);
... serialize data members ...
}
template<class Archive>
void PositionComponent::serialize(Archive &a, const unsigned int v)
{
a & boost::serialization::base_object<Component>(*this);
... serialize data members ...
}
...
I also include the Boost archive through a common header. As far as I can tell, everything looks right. There's also a "BOOST_SERIALIZATION_ASSUME_ABSTRACT" on the base Component, as "accept" is pure virtual.
When I run the program and get to the point where it serializes this stuff, I get
what(): unregistered class - derived class not registered or exported
Serialization occurs through a pointer to the base Component.
I've heard troubles involving Boost serialization and "libraries". The build system I was using, CMake, is set up to compile the program by assembling its subcomponents into libraries and then putting those together into a single executable to make the final program. Could that be the problem?
Also, Component derives from std::enable_shared_from_this (that's C++11 STL, not Boost) -- could this be the problem? If so, what can be done about it?
This is a partial answer as it doesn't explain exactly why it failed. I have managed to solve the problem by compiling the program as a single program instead of a bunch of libraries that are then statically linked together, which is how I thought I had to do it with the build system I was using since the documentation that was available online for the system was terse and when I put together the makefiles, I wasn't sure exactly how to do it. I suspect it has something to do with Boost's trouble dealing with this kind of code in libraries.