I'mm using boost to serialize and deserialize some classes
Like so:
boost::archive::xml_oarchive xmlArchive(oStringStream);
xmlArchive.register_type(static_cast<BaseMessage *>(NULL));
xmlArchive.register_type(static_cast<IncomingTradeMessage *>(NULL));
xmlArchive.register_type(static_cast<InternalRequestInfo *>(NULL));
xmlArchive.register_type(static_cast<InternalTradeTransInfo *>(NULL));
const BaseMessage* myMessage =message;
xmlArchive << make_nvp("Message", myMessage);
now my clasess get a class_id according to the order used, i dont want that, i want to control the Class_id's
so i can do something like
BOOST_SET_CLASS_ID(1234, BaseMessage);
and everywhere in my project BaseMes开发者_开发问答sage would have class_id of 1234.
How can i do such a thing
Can't you use BOOST_CLASS_EXPORT_GUID
or similar instead? I.e.
BOOST_CLASS_EXPORT_GUID(IncomingTradeMessage, "IncomingTradeMessage")
...
It will use some more bandwidth since strings are transmitted rather than integers, but it will solve your problem.
Refer to this and this for more info.
EDIT:
This compile just fine:
#include <fstream>
#include <boost/serialization/export.hpp>
#include <boost/archive/text_oarchive.hpp>
class Foo {
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & dummy1;
}
int dummy1;
public:
virtual ~Foo() {}
};
class Bar : public Foo {
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
// serialize base class information
ar & boost::serialization::base_object<Foo>(*this);
ar & dummy2;
}
int dummy2;
};
BOOST_CLASS_EXPORT_GUID(Foo, "Foo")
BOOST_CLASS_EXPORT_GUID(Bar, "Bar")
int main(int argc, char *argv[]) {
std::ofstream ofs("filename");
boost::archive::text_oarchive oa(ofs);
Foo *f = new Bar;
oa << f;
return 0;
}
I'm not sure if this is applicable in your case (if your question is specifically seeking mechanisms in boost or not), but how about strings? There's no boost facility like this that I know, but I've apply this kind of solution to our code base:
#include <iostream>
#include <string>
using namespace std;
template <class T>
const char* my_type_id()
{
return "Unknown";
}
#define REGISTER_TYPE(some_type) \
template <> inline \
const char* my_type_id<some_type>() \
{ \
return #some_type; \
}
REGISTER_TYPE(int)
REGISTER_TYPE(std::string)
int main()
{
// displays "int"
cout << my_type_id<int>() << endl;
// displays "std::string"
cout << my_type_id<string>() << endl;
// displays "Unknown" - we haven't registered char
cout << my_type_id<char>() << endl;
}
It's basically reinventing RTTI which, if you can use for production builds, makes this above solution unnecessary. We couldn't do this as it was for a software development kit and we didn't want to assume that everyone using it would have RTTI enabled.
If you need integers instead of strings, then it's easy enough to adapt this:
template <class T>
int my_type_id()
{
return -1;
}
#define REGISTER_TYPE(some_type, type_code) \
template <> inline \
int my_type_id<some_type>() \
{ \
return type_code; \
}
REGISTER_TYPE(int, 1234)
REGISTER_TYPE(std::string, 4567)
You could even avoid the overhead of a function call and just generate a class that stores these type-associated integral values as an enumerated constant (guaranteed to be an rvalue).
精彩评论