【问题标题】:Boost serialization with shared_ptr without implementing serialize() function in pointed class使用 shared_ptr 提升序列化而不在指向类中实现 serialize() 函数
【发布时间】:2013-07-16 09:23:55
【问题描述】:

在使用共享指针的 boost tutorial and example 中,它们有一个 A 类,它们创建了一个指向 A 类对象的共享指针:

boost::shared_ptr<A> spa(new A);

然后他们将其序列化:

std::ofstream ofs(filename.c_str());
boost::archive::text_oarchive oa(ofs);
oa << spa;

那么为什么A这个类必须要有这个功能呢?

void serialize(Archive & ar, const unsigned int /* file_version */); 

我想使用共享指针的原因是为了避免为我的一些复杂类定义这个函数。目前我没有使用共享指针,我使用的是真正的指针,我实际上是在序列化指针指向的地址。

【问题讨论】:

  • 序列化库怎么知道,如何序列化A 类型的对象?有人需要告诉它怎么做,这是 Boost.Serialization 处理这个问题的(一种)方式。
  • 但是我不想序列化A,我想序列化地址..
  • +1 这是一个有用的问题
  • @yonigo 我可能仍然不明白,但为此您不需要复杂的序列化库。序列化指针(地址)的值有什么用?

标签: c++ serialization boost shared-ptr


【解决方案1】:

我想使用 shared_pointer 的原因是为了避免为我的一些复杂类定义这个函数。

在我看来,这是使用共享指针的错误理由。使用共享指针是好,但原因是它为你做内存管理,所以你不必自己调用delete。在某些(极少数)情况下,使用智能指针可能不是最好的解决方案,您更愿意自己进行内存管理。这是决定是否使用智能指针的最重要标准,其次是序列化作为附带好处/麻烦。

无论如何:

我不是boost::archive 框架的专家,但似乎序列化到Archive 类比仅仅打印值更微妙,因为它还使用“版本”以防你想改变你的方式序列化您的对象,但确保与使用旧版本编写的文件具有追溯兼容性。这就是为什么仅使用对象的operator&lt;&lt;(在您的情况下是A* 或shared_ptr&lt;A&gt;)是不够的。你确实需要方法void serialize(...)。

不过,boost 提供了一个方便的宏来自动为shared_ptr&lt;A&gt; 对象定义这个方法:

BOOST_SERIALIZATION_SHARED_PTR(A)

另外,我猜它自动与A* 对象一起工作的原因是这些对象有一个默认实现。

【讨论】:

  • @yonigo 我开发了一些我之前(已删除)的评论。 :-)
【解决方案2】:

Boost documentation 中有一个很好的答案。

这是他们给出的例子:

template<class Archive, class T>
inline void save(
    Archive & ar,
    const boost::shared_ptr<T> &t,
    const unsigned int /* file_version */
){
    const T * t_ptr = t.get();
    // just serialize the underlying raw pointer
    ar <<: boost::serialization::make_nvp("px", t_ptr);
}

template<class Archive, class T>
inline void load(
    Archive & ar,
    boost::shared_ptr<T> &t,
    const unsigned int file_version
){
    T* r;
    // recover the underlying raw pointer
    ar >> boost::serialization::make_nvp("px", r);

    // To Do - match up with other shared pointers which 
    // use this same raw pointer.
    ...
}

完整的答案在 Boost 文档中。

【讨论】:

  • 这个比你之前的两次尝试好一点,但是这里还是有问题;现在您所做的一切似乎都是从文档中复制和粘贴的,而不是用您自己的话给出答案。使用引号和链接是可以的,但它们都不应该是你答案的大部分——甚至根本不需要你的答案才有意义。
猜你喜欢
  • 2012-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-12
  • 2015-01-13
  • 2014-07-01
  • 1970-01-01
相关资源
最近更新 更多