问题
See below a main() and two very simple classes. Then per Boost serialization (and what is shown) my questions are:
1) Does class B need the normal overloaded stream insertion operators '<<' and '>>' to be defined? Currently in my real code it doesn't have these.
2) Does class A in the store() and load() methods need to iterate through the map and multimap containers explicitely, storing/loading their key:value pairs explicitely? e.g. something like:
void A::store(const char* filename){
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
std::map< std::string, B >::iterator it;
BMap.size();
oa << BMap.size();
for( it = BMap.begin(); it != BMap.end(); it++ ){
oa << it->first;
oa << it->second;
}
//similar for strMultimap
}
I assume that I don't need to do this, but am not certain.
3) Assuming class B has only the two data members shown, does it need a default contructor included explicitely? (as opposed to the implicit default constructor)
4) Does B need to have an overide for the comparison operator '>'? I assume that it doesn't since this is a very simple class.
Finally, any other comments per anything that I've failed to cover is appreciated!
Example code for my above questions:
//includes ommitted
int main() {
std::string file("test.dat");
A * pA = new A;
pA->store(file.c_str());
pA->fillMaps();
//release data
pA->load(file.c_str());
return 0;
}
//includes ommitted
class A
{
friend class boost::serialization::access;
public:
std::map< std::string, B > BMap;
std::multimap< std::string, std::string > strMultimap;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & BMap;
ar & strMultimap;
}
void store(const char* filename){
std::ofstream ofs(filename);
boost::archive::text_oarchive oa(ofs);
oa << this;
}
void load(const char* filename){
std::ifstream ifs(filename);
boost::archive::text_iarchive ia(ifs);
ia >> this;
}
void fillMaps(){
//code to allocate B objects and put them in BMap and fill strMultimap with whatever number of key:value pairs
}
class B
{
friend class boost::serialization::access;
public:
std::string str;
unsigned int num;
B::B(void)
: str("a string")
, num(7)
{
}
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & str;
ar & num;
}
}
回答1:
1) You don't need stream operators for class B, but it does need a serialize() method. I had to wrap the serialization with the BOOST_SERIALIZATION_NVP
(name value pair) macro:
ar & BOOST_SERIALIZATION_NVP(someNamedValue); // use this macro for everything you want to name
There might be a way to avoid naming your map, but I don't know how that's done.
2) No, class A doesn't need map-specific serialization code. Just make sure you include <boost/serialization/map.hpp>
.
3) The implicit default constructor should be fine. You only ever need an explicit default constructor if a) you've already provided a non-default constructor or b) you want to change the behavior of the default constructor.
4) No operator < is needed :)
Here's some sample code which compiled, but I haven't run:
#include <boost/serialization/map.hpp>
struct A
{
struct B
{
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
}
};
typedef std::map<int, SomeClass> MyMap;
MyMap myMap;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & BOOST_SERIALIZATION_NVP(myMap);
}
};
来源:https://stackoverflow.com/questions/1676781/boost-serializing-of-object-containing-map-with-object-values-and-multimap-wi