4

boost :: serializationを使用して、可変メンバーにキャッシュされた派生値を含むオブジェクトをシリアル化する「最良の」方法は何ですか?

class Example
{
public:
    Example(float n) : 
        num(n),
        sqrt_num(-1.0)
    {}

    // compute and cache sqrt on first read
    float get_sqrt() const
    { 
        if(sqrt_num < 0) 
            sqrt_num = sqrt(num);
        return sqrt_num;
    }

    template <class Archive> 
    void serialize(Archive& ar, unsigned int version)
    { ... }
private:
    float num;
    mutable float sqrt_num;
};

メンテナンス上の理由から、serialize()を別々のsave()メソッドとload()メソッドに分割することは避けたいと思います。

シリアル化の1つの次善の実装:

    template <class Archive> 
    void serialize(Archive& ar, unsigned int version)
    {
        ar & num;
        sqrt_num = -1.0;
    }

これは逆シリアル化の場合を処理しますが、シリアル化の場合、キャッシュされた値は強制終了され、再計算する必要があります。

この場合のベストプラクティスは何ですか?

4

2 に答える 2

3

保存方法と読み込み方法を分割しても、シリアル化コードのコピーを2つ保持する必要はありません。それらを分割してから、共通の機能を使用して再度結合することができます。

private:
  friend class boost::serialization::access;

  BOOST_SERIALIZATION_SPLIT_MEMBER()

  template <class Archive>
  void save(Archive& ar, const unsigned int version) const {
      const_cast<Example*>(this)->common_serialize(ar, version);
  }

  template <class Archive>
  void load(Archive& ar, const unsigned int version) {
      common_serialize(ar, version);
      sqrt_num = -1;
  }

  template <class Archive>
  void common_serialize(Archive& ar, const unsigned int version) {
      ar & num;
  }

あなたはおそらく気づいたでしょうconst_cast。これは、このアイデアに対する不幸な警告です。serializeメンバー関数は操作を保存するために非constですが、メンバー関数はconstでsaveある必要があります。ただし、シリアル化するオブジェクトが元々constとして宣言されていない限り、上記のようにキャストしても安全です。ドキュメントには、constメンバーのキャストの必要性が簡単に記載されています。これは似ています。

ex1上記の変更により、コードはとの両方に対して「2」を正しく出力しex2、シリアル化コードのコピーを1つだけ維持する必要があります。このloadコードには、オブジェクトの内部キャッシュの再初期化に固有のコードのみが含まれています。save関数はキャッシュにアクセスしません。

于 2010-05-18T07:48:11.450 に答える
2

フィールドをチェックして、Archive::is_loadingtrueの場合はキャッシュされた値をロードできます。

template <class Archive> 
void serialize(Archive& ar, unsigned int version)
{
    ar & num;
    if(Archive::is_loading::value == true)
        sqrt_num = -1.0;
}
于 2013-10-30T20:35:14.660 に答える