#include <fstream>
#include <vector>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/base_object.hpp>
class Foo {
public:
Foo(int x) : x(x) {}
virtual void foo() const { std::cout << "Foo! " << x << "\n"; }
protected:
int x;
Foo() {}
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & x;
}
};
class Bar1 : public Foo {
public:
Bar1(int x) : Foo(x), bar("Hello!") {}
virtual void foo() const { std::cout << "Bar1! " << x << " " << bar << "\n"; }
private:
friend class boost::serialization::access;
Bar1() {}
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & boost::serialization::base_object<Foo>(*this);
ar & bar;
}
std::string bar;
};
class Bar2 : public Foo {
public:
Bar2(int x) : Foo(x), bar(3.14159265) {}
virtual void foo() const { std::cout << "Bar2! " << x << "\n"; }
private:
friend class boost::serialization::access;
Bar2() {}
template<class Archive>
void serialize(Archive & ar, const unsigned int version) {
ar & boost::serialization::base_object<Foo>(*this);
ar & bar;
}
double bar;
};
void printPtrVec(const std::vector<Foo *>& hello) {
for(std::vector<Foo *>::const_iterator it = hello.begin(); it != hello.end(); ++it) {
(*it)->foo();
}
}
int main(int argc, char *argv[]) {
std::vector<Foo *> hello;
hello.push_back(new Foo(1));
hello.push_back(new Bar1(2)); //causes exception
hello.push_back(new Bar2(3)); //causes exception
std::ofstream ofs("tmp.txt");
boost::archive::text_oarchive oa(ofs);
oa << hello;
ofs.close();
printPtrVec(hello);
std::cout << "Serialized!\n";
hello.clear();
std::ifstream ifs("tmp.txt");
boost::archive::text_iarchive ia(ifs);
ia >> hello;
ifs.close();
std::cout << "Deserialized!\n";
printPtrVec(hello);
std::cout << "Successful!\n";
std::cin.get();
return 0;
}
boost serialization and polymorphic collection
I tried to construct a minimal program with a vector polymorphically storing a number of objects of different classes, and then use boost serialization to serialize/deserialize it. The problem is, the program below crashes when I don't comment out the two lines marked with "//causes exception". I'm not surprised, because as far as I know there's no way for the serialization framework to properly construct the necessary objects with the right type, because in C++ there's simply no generic way of constructing an object given typeinfo, an id or similar, unless I create my own factory class for this. So, how should scenarios such as the one below be handled in practice? E.g. I have a polymorphic collection of classes allocated on the heap and would like to serialize/deserialize it.
Edit: sexier indentation
[Edited by - all_names_taken on August 15, 2009 3:51:47 AM]
Where does it crash? I have no experience with boost so I'm possibly not in the position to actually help you but does it crash when you push the value, or does it crash later in the program when you have already pushed the value's (now I reread the sentence its really badly formulated:P).
You need to export those derived classes :
This should provide the serialization library with the necessary information to create the correct objects.
#include <boost/serialization/export.hpp>//...BOOST_CLASS_EXPORT(Bar1);BOOST_CLASS_EXPORT(Bar2);//...
This should provide the serialization library with the necessary information to create the correct objects.
Great, now it works! I'll have to take a look out how they implemented such an awesome thing!
One more thing I forgot to ask, why do I get this warning when compiling the above program (and the fixed program) with MSVC?
One more thing I forgot to ask, why do I get this warning when compiling the above program (and the fixed program) with MSVC?
* boost/archive/detail/oserializer.hpp(538) : warning C4099: 'boost::serialization::static_warning_impl<false>::STATIC_WARNING' : type name first seen using 'struct' now seen using 'class'* boost/serialization/static_warning.hpp(115) : see declaration of 'boost::serialization::static_warning_impl<false>::STATIC_WARNING'* boost/archive/detail/common_oarchive.hpp(64) : see reference to function template instantiation 'void boost::archive::save<Archive,T>(Archive &,T &)' being compiled with [ Archive=boost::archive::text_oarchive, T=std::vector<Foo *> ]* boost/archive/basic_text_oarchive.hpp(75) : see reference to function template instantiation 'void boost::archive::detail::common_oarchive<Archive>::save_override<T>(T &,int)' being compiled with [ Archive=boost::archive::text_oarchive, T=std::vector<Foo *> ]* boost/archive/detail/interface_oarchive.hpp(64) : see reference to function template instantiation 'void boost::archive::basic_text_oarchive<Archive>::save_override<T>(T &,int)' being compiled with [ Archive=boost::archive::text_oarchive, T=std::vector<Foo *> ] .\main.cpp(107) : see reference to function template instantiation 'Archive &boost::archive::detail::interface_oarchive<Archive>::operator <<<std::vector<_Ty>>(T &)' being compiled with [ Archive=boost::archive::text_oarchive, _Ty=Foo *, T=std::vector<Foo *> ]
This is a warning generated by boost.serialisation in two circumstances, when you are serialising an object with tracking set to boost::serialization::track_never or when you are serialising a non-const object which isn't marked as boost::serialization::track_never, it is designed to trap possible errors with using the library. Here is a rationale behind it.
You are doing the latter. If you const_cast your object before serialising it you can remove the warning :
You can read more about object tracking (including the default tracking levels) here.
Good luck!
You are doing the latter. If you const_cast your object before serialising it you can remove the warning :
oa << const_cast<const std::vector<Foo *>&>(hello);
You can read more about object tracking (including the default tracking levels) here.
Good luck!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement