boost :: serialization如何与C++ 11中的std :: shared_ptr一起使用?

fik*_*tor 24 c++ boost shared-ptr boost-serialization c++11

我知道有一个用于序列化Boost模块boost::shared_ptr,但我找不到任何东西std::shared_ptr.

另外,我不知道如何轻松实现它.我怕以下代码

namespace boost{namespace serialization{
template<class Archive, class T>
inline void serialize(Archive & ar, std::shared_ptr<T> &t, const unsigned int version)
{
  if(Archive::is_loading::value) {T*r;ar>>r;t=r;}
  else {ar<<t.get();}
}
}}//namespaces
Run Code Online (Sandbox Code Playgroud)

不起作用.实际上,如果某个对象被多次引用,它将被第一次运行加载ar>>r,之后只会复制一个指针.但是,我们会创建shared_ptr指向它的多个对象,因此会多次破坏它.

有什么想法吗?

关于我正在使用的系统的一些技术细节:

  • 操作系统:Ubuntu 11.10(x64)
  • 编译器:g ++(Ubuntu/Linaro 4.6.1-9ubuntu3)4.6.1
  • 升级版:1.46.1(已安装sudo apt-get install libboost-dev)

den*_*nim 15

嘿伙计们,我终于找到了一个如何使用boost序列化序列化std :: shared_ptr的解决方案.您只需要以下代码(解释如下):

#include <boost/serialization/split_free.hpp>
#include <boost/unordered_map.hpp>

//---/ Wrapper for std::shared_ptr<> /------------------------------------------

namespace boost { namespace serialization {

template<class Archive, class Type>
void save(Archive & archive, const std::shared_ptr<Type> & value, const unsigned int /*version*/)
{
    Type *data = value.get();
    archive << data;
}

template<class Archive, class Type>
void load(Archive & archive, std::shared_ptr<Type> & value, const unsigned int /*version*/)
{
    Type *data;
    archive >> data;

    typedef std::weak_ptr<Type> WeakPtr;
    static boost::unordered_map<void*, WeakPtr> hash;

    if (hash[data].expired())
    {
         value = std::shared_ptr<Type>(data);
         hash[data] = value;
    }
    else value = hash[data].lock();
}

template<class Archive, class Type>
inline void serialize(Archive & archive, std::shared_ptr<Type> & value, const unsigned int version)
{
    split_free(archive, value, version);
}

}}
Run Code Online (Sandbox Code Playgroud)

此代码简单地序列化函数save()中由std :: shared_ptr管理的对象.如果多个std :: shared_ptr实例指向同一个对象,则序列化将自动关注仅存储一次.神奇的事情发生在load()中,其中boost序列化返回一个指向对象(数据)的原始指针.这个原始指针在一个哈希中查找,该哈希为每个原始指针保存一个weak_ptr.如果散列中的weak_ptr过期,我们可以安全地创建一个新的shared_ptr实例,让它管理原始指针并在散列中存储weak_ptr.如果weak_ptr没有过期,我们只需将其锁定即可返回shared_ptr.这样引用计数是正确的.

  • 我认为常规的std :: map可能会更好.此外,weak_ptr可能在检查它和调用lock()之间到期.而是检查lock()的结果.尽管如此投票. (2认同)

jos*_*oli 14

从Boost 1.56开始,序列化库内置了对std :: shared_ptr的支持.如果可以使用更新版本的库,则无需实现自己的序列化辅助函数.

  • 这是正确的答案.它只需要完成:添加`#include <boost/serialization/shared_ptr.hpp>`来使用它! (3认同)