c++とboostを用いたシリアライズ

シリアライズとは?

シリアライズとは メモリ上に存在するオブジェクトを、バイト列に変換する処理. このバイト列が、1列に並んでいるため、シリアライズと呼ばれる。 反対の操作はデシリアライズと呼ばれる.

いつ使われる?

シリアライズは、オブジェクトをファイルなどに保存したり、ネットワーク送信したりする際によく利用される。

C++でのシリアライズ 〜クラスをシリアル化できるようにしよう〜

標準ライブラリとして、iostreamといったストリーム入出力ライブラリで、バイト列の入出力は可能だが,オブジェクトをバイト列に変換する機能はない.

Boostライブラリを使うことで、これは解決可能である.

具体的にはboost::serializationというシリアライズライブラリが提供されている.

これの使い方を以下で説明する.

コード:クラスをシリアライズする

クラスにserialize member関数テンプレートを追加することで、そのクラスがシリアライズ可能になる.

class Customer {
private:
  std::string name_;
  int age_;
  
  friend class boost::serialization::access;
  template<class Archive>
    void serialize(Archive& ar, const unsigned int version)
    {
      ar & name_;
      ar & age_;
    }
};

template<class Archive> void serialize(Archive& ar, const unsigned int version) というのが,serialize member関数テンプレートである.

以下で詳しく見ていこう

Archive型の引数ar

Archive型の引数arには シリアライズ時にはシリアライズ先となるオブジェクトが、デシリアライズ時にはデシリアライズ元となるオブジェクトが代入される。

今回の例では、main関数で作成したストリームが代入される.

&演算子

      ar & name_;
      ar & age_;

C++のストリームなどでは、出力に<<演算子、読込に>>演算子を使うが、boost::serializeでは &を用いて operatorで、Arichiveをシリアライズ/デシリアライズすることができる。 <<演算子や>>演算子も使えるが、この関数は出力と入力両方を受け持つので&演算子を使う

int version

versionは、保存形式のバージョンを示す数値

friend指定

boost::serializationライブラリのprivateメンバであるserialize関数にアクセスするためにfriend指定が必要 friend指定を省略したいからといって、serialize関数をpublic指定にしてはいけないので注意.

データを入出力

上でつくったクラスのシリアライズ・デシリアライズのやり方を説明する.

基本は標準入出力と同じやり方で可能.即ちファイルオブジェクトの作成と実際のデータの書き出し・読み込みの2つのプロセスを経る.

int main(){
   Customer customer;
   
// serialize
   std::ofstream ofs("output.txt");
   boost::archive::text_oarchive oa(ofs);
   
   oa << customer;
   
   ofs.close();
   
// deserialize
   std::ifstream ifs("output.txt");
   boost::archive::text_iarchive ia(ifs);
   
   ia >> customer;
   
   ifs.close();
   return 0;
}

bxyxvzz.hatenablog.com