我有几个要序列化并通过tcp套接字发送的“命令”。
每个命令由不同的数据结构表示,但所有命令的某些部分相同(我将其存储在Base
类中。)
这里是一个例子:
enum class Operations {
LOGOUT = 0,
LOGIN,
};
struct Base {
friend class boost::serialization::access;
Operations operationID;
int id;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & operationID;
ar & id;
}
};
struct Logout : public Base {
friend class boost::serialization::access;
string sessionId;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<Base>(*this);
ar & sessionId;
}
};
struct Login : public Base {
friend class boost::serialization::access;
string login;
string password;
template<class Archive>
void serialize(Archive &ar, const unsigned int version)
{
ar & boost::serialization::base_object<Base>(*this);
ar & login;
ar & password;
}
};
另一端不知道收到了哪个命令。想法是对Base
部分进行反序列化,然后阅读operationID
,然后选择合适的类对整个命令进行反序列化。
但是经过几次实验,它似乎是不可能的。我是正确的,并且boost序列化不能以这种方式工作吗?解决此任务的通常方法是什么?
更新:
详细说明。
让序列化的Logout
到文件:
std::ofstream ofs("filename");
Logout data;
data.id = 42;
data.operationID = Operations::LOGOUT;
data.sessionId = "someSession";
boost::archive::text_oarchive oa(ofs);
oa << data;
并且此代码将正确读取Logout
:
Logout parseLogout() {
std::ifstream ifs("filename");
Logout data;
boost::archive::text_iarchive ia(ifs);
ia >> data;
return data;
}
但是我不知道Logout
中的Login
或filename
是什么。
这就是为什么我想要这样的东西:
Base data;
{
std::ifstream ifs("filename");
boost::archive::text_iarchive ia(ifs);
ia >> data;
}
switch (data.operationID) {
case Operations:LOGOUT: data = (Base) ParseLogout(); break;
case Operations:LOGIN: data = (Base) ParseLogin(); break;
}
但是data.operationID
的值不是我想要的。
临时的,我用Container
类包装了所有类,这些类可以将我所有的类数据存储为vector<char>
,并且它有type
知道要存储哪种类。但是也许存在更优雅的解决方案?