Opened 12 years ago
Closed 12 years ago
#4536 closed Bugs (fixed)
serializing diamond shaped classes using virtual inheritance
Reported by: | Owned by: | Robert Ramey | |
---|---|---|---|
Milestone: | Boost 1.44.0 | Component: | serialization |
Version: | Boost 1.39.0 | Severity: | Problem |
Keywords: | virtual inheritance diamond shaped classes | Cc: |
Description
I am having some trouble with serializing diamond shaped classes which are using virtual inheritance with boost version 1.39 and above.
Compile the following problem on Visual Studio 2008 is ok but run the program will result an assert in base_object.hpp around line 103
return static_cast<type &>(d);
/*start of the sample program*/ #include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/serialization/nvp.hpp> #include <boost/static_assert.hpp> #include <iomanip> #include <iostream> #include <fstream> #include <string>
#include <boost/serialization/map.hpp> #include <boost/serialization/utility.hpp> #include <boost/serialization/base_object.hpp> #include <boost/serialization/nvp.hpp> #include <boost/archive/xml_iarchive.hpp> #include <boost/archive/xml_oarchive.hpp> #include <boost/serialization/export.hpp>
#include <cstddef> NULL #include <fstream> #include <iostream>
#include <boost/config.hpp> #include <cstdio> remove #if defined(BOOST_NO_STDC_NAMESPACE) namespace std{
using ::remove;
} #endif
#define DECLARE_BOOST_SERIALIZATION_SPECIALIZE() \
template<class Archive> void serialize(Archive &ar, const unsigned int version); \ template<class Archive> void doSerialize(Archive &ar, const unsigned int version); \ template<> void serialize(boost::archive::xml_iarchive &ar, const unsigned int version){doSerialize((ar),version); } \ template<> void serialize(boost::archive::xml_oarchive &ar, const unsigned int version){doSerialize((ar),version);}
#define DECLARE_BOOST_SERIALIZATION_GENERIC() \
template<class Archive> void serialize(Archive &ar, const unsigned int version) {doSerialize(ar,version); } \ template<class Archive> void doSerialize(Archive &ar, const unsigned int version);
class B_GraphObject { public:
B_GraphObject() : m_objectId(0) {} B_GraphObject(int i) : m_objectId(i) { }
#ifdef SSONESERIALIZEINTERFACE
DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() #endif
bool operator==(const B_GraphObject& another) const {
return m_objectId == another.m_objectId;
} make polymorphic by marking at least one function virtual virtual ~B_GraphObject() {};
private:
int m_objectId;
};
template<class Archive> void B_GraphObject::doSerialize(Archive &ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_NVP(m_objectId);
}
class B_GraphNode : virtual public B_GraphObject { public:
B_GraphNode(){} B_GraphNode(int i) : B_GraphObject(i),
m_nodeWeigth(i+1){}
#ifdef SSONESERIALIZEINTERFACE DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE()
#endif
private:
double m_nodeWeigth;
};
template<class Archive> void B_GraphNode::doSerialize(Archive &ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphObject);
ar & BOOST_SERIALIZATION_NVP(m_nodeWeigth);
}
class B_GraphNode2 : virtual public B_GraphObject { public:
B_GraphNode2(){} B_GraphNode2(int i) : B_GraphObject(i+1),
m_nodeWeigth(i+2){
} #ifdef SSONESERIALIZEINTERFACE DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() #endif private:
double m_nodeWeigth;
};
template<class Archive> void B_GraphNode2::doSerialize(Archive &ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphObject);
ar & BOOST_SERIALIZATION_NVP(m_nodeWeigth);
}
class B_GraphChildNode : public B_GraphNode,
public B_GraphNode2 {
public:
B_GraphChildNode() {} B_GraphChildNode(int i) : B_GraphNode(i), B_GraphNode2(i+2), m_nodeWeigth(i+10){}
public: #ifdef SSONESERIALIZEINTERFACE DECLARE_BOOST_SERIALIZATION_GENERIC() #else DECLARE_BOOST_SERIALIZATION_SPECIALIZE() #endif private:
double m_nodeWeigth;
};
BOOST_CLASS_EXPORT(B_GraphChildNode)
template<class Archive> void B_GraphChildNode::doSerialize(Archive &ar, const unsigned int version) {
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphNode); ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(B_GraphNode2); ar & BOOST_SERIALIZATION_NVP(m_nodeWeigth);
}
int main() {
const char*testfile = "diamond.xml";
B_GraphChildNode *B_GraphChildNodePtr = new B_GraphChildNode( 3 );
const B_GraphObject* bp = B_GraphChildNodePtr; {
std::ofstream ofs(testfile); boost::archive::xml_oarchive oa(ofs); oa << BOOST_SERIALIZATION_NVP(bp);
}
B_GraphObject* bp2; {
std::ifstream ifs(testfile); boost::archive::xml_iarchive ia(ifs); ia >> BOOST_SERIALIZATION_NVP(bp2);
}
return 0;
} /*end of the sample program*/
If I compile the program by defining SSONESERIALIZEINTERFACE in Visual Studio 2008, the program runs ok.
Using boost version 1.38, the sample program runs ok regardless defining SSONESERIALIZEINTERFACE or not.
There must be something changed in 1.39 which is causing the problem.
Thanks, Hanyu
There have been changes in 1.44 - soon to be released which I believe will address this issue. So for now I'm going to mark this as fixed. Please feel free to re-open this if you have the problem after testing with the version 1.44.
Robert Ramey