序列化模式类似于boost::序列化
serialization pattern similar to boost::serialization
我有一堆类,可以通过以下接口从JSON对象解析并序列化为JSON对象:
class Message
{
public:
virtual ~Message() {}
virtual void parse(const Json::Value &v) = 0;
virtual void serialize(Json::Value &v) const = 0;
};
我想实现一个类似于boost::serialization
的模式,这样我就必须在对象中只定义一个方法(void setup(...)
,是的,我知道,这是一个糟糕的命名选择(,它可以双向工作(解析和序列化(。这也有提供抽象层的好处,这样将来我就可以切换到不同的序列化(YAML?BSON?CBOR?(,而无需重写每个对象中的所有序列化代码。
所以我做了以下事情:
class Message2;
struct MessageFields
{
Json::Value *outValue;
const Json::Value *inValue;
virtual void map(const std::string &name, bool *field) {
*field = (*inValue)[name].asBool();
}
virtual void map(const std::string &name, const bool *field) {
(*outValue)[name] = *field;
}
virtual void map(const std::string &name, int *field) {
*field = (*inValue)[name].asInt();
}
virtual void map(const std::string &name, const int *field) {
(*outValue)[name] = *field;
}
virtual void map(const std::string &name, std::string *field) {
*field = (*inValue)[name].asString();
}
virtual void map(const std::string &name, const std::string *field) {
(*outValue)[name] = *field;
}
...
};
以及:
// the new base class:
class Message2 : public Message
{
virtual ~Message2() {}
// the new method to implement:
virtual void setup(MessageFields &fields) const = 0;
virtual void parse(const Json::Value &v)
{
MessageFields fields;
fields.inValue = &v;
setup(fields);
}
virtual void serialize(Json::Value &v) const
{
MessageFields fields;
fields.outValue = &v;
setup(fields);
}
};
在我的对象中,而不是实现两种方法:
// class SomeObject : public Message { public: std::string node_name; };
void SomeObject::parse(const Json::Value &v)
{
node_name = v["node_name"].asString();
}
void SomeObject::serialize(Json::Value &v) const
{
v["node_name"] = node_name;
}
只需要实现:
// class SomeObject : public Message2 { public: std::string node_name; };
void SomeObject::setup(serialization::MessageFields &fields) const
{
fields.map("node_name", &node_name);
}
除了在写完这篇文章后,我意识到setup(...)
就是const
,所以对MessageFields::map(...)
的调用总是解析为const版本。
为了解决这个问题,我必须编写两个相同版本的setup(...)
方法,一个是const
,另一个不是,但这种方法违背了只编写一个方法来执行这两个操作的最初目的。
你知道怎么解决这个问题吗?
如果不可能保持常量的正确性(正如我所怀疑的(,那么将Message::serialize
和Message2::setup
更改为非常量的解决方案也会起作用。
根据@BartoszKP的建议,我从void Message2::setup(MessageFields &fields)
中删除了const
。
这也需要改变:
void Message2::serialize(Json::Value &v) const
{
serialization::MessageFields fields;
fields.outValue = &v;
const_cast<Message*>(this)->setup(fields);
}
并且只有非常数MessageFields::map(...)
方法,该方法将通过检查在MessageFields::inValue
和MessageFields::outValue
之间设置了哪个值来判断两个操作中的哪一个正在进行(即解析或序列化(。
注意:我不能接受这个答案,因为根据https://isocpp.org/wiki/faq/const-correctness
- 如何使用boost::具有嵌套结构和最小代码更改的序列化
- C++boost序列化多态性问题
- 将 boost 序列化对象的 asio::streambuf 表示转换为 Beast 的 DynamicBody req.body()
- 如何在 boost::asio 中将打包的结构作为消息传递?(无序列化)
- 如何使用 Boost 序列化mersenne_twister_engine?
- boost::序列化中的派生类偏移量计算.有效吗?
- C++ Boost - 序列化错误 - 将"const B"作为"this"参数
- 序列化模式类似于boost::序列化
- 序列化和反序列化boost共享指针
- 使用 Boost::Serialization 序列化具有 std::mt19937_64 成员的类
- boost::container::vector 无法用谷物序列化?
- 使用 Boost 对具有 const 成员的类进行序列化
- 使用 boost::序列化代码将 *this 传递给模板函数会产生错误
- C++ 从 Boost object_pool构造的指针的 Boost 二进制序列化
- 如何使用谷物序列化 boost::p tr_vector
- 如何用谷物序列化 boost::uuid
- 派生类行程的序列化Boost断言
- 如何使用Boost序列化来序列化Boost scoped_array
- 如何序列化 <boost::shared_ptr<void *>> 类型的列表变量
- 我如何重载序列化boost函数,使其一个用于文件存储,另一个用于tcp消息