stefhane stefhane - 21 days ago 5
C++ Question

Use Boost serialization with forward declaration class and inheritance

I am using boost serialization to store and load several classes. My goal is to use serialization on one class which contain the other classes, and so the other classes will be serialize.

But the problem is these classes contain forward declaration and inheritance, and I can't make boost serialization work with these classes.

I have a problem at the compilation, specifically on forward declaration, with these error :

error: invalid use of incomplete type ‘class C’
error: forward declaration of ‘class C’
error: ‘value’ is not a member of ‘boost::is_polymorphic<C>’
...


Can someone tell me what is wrong with my code? Am I missing something?
Is my code for serializing derived and forward declared classes correct?

A.h :

#include <boost/serialization/access.hpp>
#include <boost/serialization/vector.hpp>

class B;
class C;

class A {

private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & m_Bvector;
}

protected:
vector<B*> m_Bvector;
vector<C*> m_Cvector;

/*....*/

}


NB : the vector m_Bvector can contain B* or/and C* objects

B.h :

#include <boost/serialization/access.hpp>
#include "A.h"

class B {

private :
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & m_someInt;
}

protected :
int m_someInt;

/*....*/

}


C.h :

#include <boost/serialization/base_object.hpp>
#include "B.h"

classe C : public B {

private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int version) {
ar & boost::serialization::base_object<B>(*this);
ar & m_someOtherInt;
}

protected:
int m_someOtherInt;

/*....*/


}

And this is my method to call save and load functions :

SerializationManager.h :

#include <A.h>
#include <C.h>
#include <boost/serialization/export.h>

BOOST_CLASS_EXPORT(C);

class SerializationManager {

/*....*/

public:
bool save(string filename);
bool load(string filename);

protected:
A* m_classToSave;

}


SerializationManager.cpp :

#include "SerializationManager.h"
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <fstream>
#include <sstream>

bool SerializationManager::save(string filemname)
{

std::ofstream outputFile(filemname);
assert(outputFile.good());
boost::archive::text_oarchive oTextArchive(outputFile);

oTextArchive << m_classToSave;

return true;
}

bool SerializationManager::load(string filename)
{
delete m_classToSave;

std::ifstream ifs( filename );
assert(ifs.good());
boost::archive::text_iarchive ia(ifs);

// restore the schedule from the archive
ia >> m_classToSave;

return true;
}

/* ... */

Answer

Boost needs to know whether types are virtual (have any virtual methods, i.e. usually implemented with a vtable) so it can rely on typeid and dynamic_cast to return runtime-fidelity values.

You're trying to instantiate the serialization mechanics before the definition of the types is available (the types are incomplete when only forward-declared) so it cannot generate the serialization code.