How do I avoid including the headers of every class that needs to be BOOST serialised?
I have the following situation (simplified):
a.h:
#include <boost/serialisation/serialisation.hpp>
class B;
using namespace std; using namespace boost;
class A {
B *b;
template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar开发者_JAVA技巧 & b; }
};
b.h:
#include <boost/serialisation/serialisation.hpp>
class C;
using namespace std; using namespace boost;
class B {
C *c;
template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & c; }
};
c.h:
#include <boost/serialisation/serialisation.hpp>
using namespace std; using namespace boost;
class C {
int somevar;
template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & somevar; }
};
main.cxx:
#include <boost/archive/text_oarchive.hpp>
#include <fstream>
#include "a.h"
#include "b.h"
#include "c.h"
using namespace std; using namespace boost;
int main() {
A a; // Create the object
ofstream ofs("save");
archive::text_oarchive oa(ofs);
oa << a; // Save the object
return 0;
}
Now, the problem is that I have to include the header files of all the classes that I want to serialise in the saving function (in this case right inside main). The problem with that is that there are a lot more than three classes, and they are much more complicated, resulting in a compilation bottleneck at this point.
I only recently begun using boost serialisation, but I've looked over the documentation and searched on both google and here, so I figure I've missed something obvious.
Does anybody have a solution for this such that only "a.h" needs to be included and not "b.h", "c.h", etc?
EDIT: This is hopefully the crucial part of the compilation error that occurs if I comment out the #include "b.h" and "c.h" lines:
main.cxx:17:1: instantiated from here
/usr/include/boost/type_traits/is_abstract.hpp:72:4: error: incomplete type ‘B’ not allowed
I think you could use explicit instantiation, and then define your serialize member functions in .cpp files. Then a.cpp can include b.h and c.h as needed, and users of a.h don't need to do that anymore.
Look into the pimpl-idiom examples http://www.boost.org/doc/libs/1_46_1/libs/serialization/example/demo_pimpl_A.hpp (header) and http://www.boost.org/doc/libs/1_46_1/libs/serialization/example/demo_pimpl_A.cpp (source file) for how to do that.
Disclaimer: I know nothing of boost serialisation.
Since you have template member functions serialize
which have to have inline definitions, which are using the members, you should #include
the header files for those members instead of just declaring eg class B;
.
This will mean that main will only have to #include "a.h"
in main and you shouldn't get compiler errors.
First of all, if there is a method, any method, that needs to access A, B and C, there is simply no other way than to make A, B and C visible to that method, and in yur case tha means including all 3 header files. So the compiler bottlenck you talk about cannot be solved.
Second, you should be able to use non-invasive functions for Boost's serialization. Not sure if that solves your particular problem but it's definitely worth a try and it does move all serialization related stuff into one single header file.
//header myserialization.h
#include "a.h"
#include "b.h"
#include "c.h"
template<class Archive>
void serialize(Archive & ar, const unsigned int version, A& a) { ar & a.*b; }
template<class Archive>
void serialize(Archive & ar, const unsigned int version, B& b) { ar & b.*c; }
template<class Archive>
void serialize(Archive & ar, const unsigned int version, C& c) { ar & c.somevar; }
精彩评论