2

考虑以下序列化示例,当此数据为 const 且序列化函数不是 const 函数时,boost 如何处理保存数据?

某处有 const 演员吗?

  struct Settings
  {
    Settings();
    uint32_t    buffers_size;
    uint32_t    messages;
  };

  template < class Archive >
  void serialize(Archive& ar, Settings& settings, unsigned int /*version*/)
  {
    using boost::serialization::make_nvp;
    ar 
      & make_nvp< uint32_t >("buffers_size", settings.buffers_size )
      & make_nvp< uint32_t >("messages", settings.messages);
  }
4

1 回答 1

2

据我所知,在保存对象之前,constness 确实被抛弃了。我认为相关代码在oserializer.hpp

template<class Archive, class T>
BOOST_DLLEXPORT void oserializer<Archive, T>::save_object_data(
    basic_oarchive & ar,    
    const void *x
) const {
    // make sure call is routed through the highest interface that might
    // be specialized by the user.
    BOOST_STATIC_ASSERT(boost::is_const< T >::value == false);
    boost::serialization::serialize_adl(
        boost::serialization::smart_cast_reference<Archive &>(ar),
        * static_cast<T *>(const_cast<void *>(x)),
        version()
    );
}

在调用这个方法之前,序列化的对象引用变成了a const void *,对应这里的第二个参数。此指针的 const 性被丢弃,生成的指针被转换为适当的指针类型,然后被取消引用。

这提出了在尝试序列化const对象时调用未定义行为的可能性的问题:如果serialize成员/自由函数以某种方式修改了对象,那么创建const对象并将其保存到存档将是未定义行为,并且在编译时不会被注意到-时间!

如果将函数拆分为saveload,则必须标记saveconst,以防止意外修改对象。

于 2012-12-18T13:55:50.270 回答