boost::使用可变成员进行序列化
使用 boost::serialization,序列化在可变成员中包含缓存的派生值的对象的“最佳”方法是什么?
class Example
{
public:
Example(float n) :
num(n),
sqrt_num(-1.0)
{}
// compute and cache sqrt on first read
float get_sqrt() const
{
if(sqrt_num < 0)
sqrt_num = sqrt(num);
return sqrt_num;
}
template <class Archive>
void serialize(Archive& ar, unsigned int version)
{ ... }
private:
float num;
mutable float sqrt_num;
};
出于维护原因,我想避免将 serialize() 拆分为单独的 save() 和 load() 方法。
序列化的一种次优实现:
template <class Archive>
void serialize(Archive& ar, unsigned int version)
{
ar & num;
sqrt_num = -1.0;
}
这可以处理反序列化情况,但在序列化情况下,缓存的值将被终止并且必须重新计算。
在这种情况下,最佳实践是什么?
Using boost::serialization, what's the "best" way to serialize an object that contains cached, derived values in mutable members?
class Example
{
public:
Example(float n) :
num(n),
sqrt_num(-1.0)
{}
// compute and cache sqrt on first read
float get_sqrt() const
{
if(sqrt_num < 0)
sqrt_num = sqrt(num);
return sqrt_num;
}
template <class Archive>
void serialize(Archive& ar, unsigned int version)
{ ... }
private:
float num;
mutable float sqrt_num;
};
I'd like to avoid splitting serialize() into separate save() and load() methods, for maintenance reasons.
One suboptimal implementation of serialize:
template <class Archive>
void serialize(Archive& ar, unsigned int version)
{
ar & num;
sqrt_num = -1.0;
}
This handles the deserialization case, but in the serialization case, the cached value is killed and must be recomputed.
What is the best practice in this case?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
拆分保存和加载方法并不意味着您必须维护序列化代码的两个副本。您可以将它们分开,然后使用通用函数将它们重新连接起来。
您可能注意到了
const_cast
。这是对这个想法的一个不幸的警告。虽然serialize
成员函数对于保存操作来说是非常量的,但save
成员函数需要是 const。不过,只要您要序列化的对象最初没有声明为 const,就可以安全地将其丢弃,如上所示。文档 简要提到需要强制转换 const成员;这很相似。通过上述更改,您的代码将为
ex1
和ex2
正确打印“2”,并且您只需维护一份序列化代码副本。load
代码仅包含特定于重新初始化对象内部缓存的代码;save
函数不会触及缓存。Splitting your saving and loading methods doesn't mean you have to maintain two copies of your serialization code. You can split them and then join them back again with a common function.
You probably noticed the
const_cast
. That's an unfortunate caveat to this idea. Although theserialize
member function is non-const for saving operations, thesave
member function needs to be const. As long as the object you're serializing wasn't originally declared const, though, it's safe to cast it away as shown above. The documentation briefly mentions the need to cast for const members; this is similar.With the changes above, your code will correctly print "2" for both
ex1
andex2
, and you only have to maintain one copy of the serialization code. Theload
code only contains code specific to re-initializing the object's internal cache; thesave
function doesn't touch the cache.您可以检查
Archive::is_loading
字段,如果为 true,则加载缓存的值。You can check the
Archive::is_loading
field, and load cached values if it's true.