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()
    );
}

このメソッドが呼び出される前に、シリアル化されたオブジェクト参照は、const void *ここでの 2 番目のパラメーターに対応する に変換されます。このポインターの定数はキャストされず、結果のポインターは適切なポインター型にキャストされ、逆参照されます。

constこれにより、オブジェクトをシリアル化しようとすると未定義の動作が発生する可能性があるという問題が生じます。serializeメンバー/フリー関数がオブジェクトを何らかの形で変更する場合、オブジェクトを作成constしてアーカイブに保存すると未定義の動作になり、コンパイル時に気付かれません-時間!

関数をsaveとに分割する場合は、としてloadマークする必要があります。これにより、誤ってオブジェクトを変更するのを防ぐことができます。saveconst

于 2012-12-18T13:55:50.270 に答える