c++ - boost序列化实际上是如何保存const对象的

标签 c++ serialization boost constants boost-serialization

考虑下面的序列化示例,当数据为 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);
  }

最佳答案

据我所知,常量确实在保存对象之前被丢弃了。我认为相关代码在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()
    );
}

在调用该方法之前,序列化的对象引用会变成一个const void *,对应这里的第二个参数。该指针的常量性被强制转换,并将生成的指针强制转换为适当的指针类型,然后取消引用。

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

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

关于c++ - boost序列化实际上是如何保存const对象的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13928979/

相关文章:

c++ - 在 boost::asio::serial_port 上解锁同步读取

C++ - 循环依赖(在模板化基类中使用子类的内部类型)

c++:搜索忽略重音字符

python - 在 django rest 框架中使用 request.user 进行模型反序列化

qt - 将 QHash 序列化为 QByteArray

boost - 计算 Boost 库中的均值和矩

C++ 智能指针性能

c++ - pageView 中的 ScrollView

c# - 使用隔离存储和 ProtectedData 保存用户凭据

c++ - 如何知道异步状态机何时终止。 ( boost::状态图)