ねむみ高まる

文章力がないので、文章を書く練習をしています。

boost::serializationを使ってみた

C++シリアライズを使ったコードを書いたことがなかったので、勉強のためにboost::serializationを使ってみました。

環境構築

Macを使っており、boostはbrewbrew install boost で入れることができました(入れたの自体は大分前です)。

~/.bash_profile に以下のようにインクルードとライブラリのパスを追加しました。

export CPATH="/usr/local/Cellar/boost/1.67.0_1/include":$CPATH
export LIBRARY_PATH="/usr/local/Cellar/boost/1.67.0_1/lib":$LIBRARY_PATH

ソースコード

#include <iostream>
#include <string>
#include <fstream>

#include <boost/serialization/serialization.hpp>
#include <boost/serialization/string.hpp>

#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>

using namespace std;

class Human {
public:
    Human()
    : m_name("")
    , m_age(0)
    {}

    Human(string name, int age)
    : m_name(name)
    , m_age(age)
    {}

public:
    void Print() { 
        cout << "name: " << m_name << endl;
        cout << "age : " << m_age << endl;
    }

private:
    string m_name;
    int m_age;

    friend class boost::serialization::access;
    template<typename Archive>
    void serialize(Archive& ar, const unsigned int version) {
        ar & m_name;
        ar & m_age;
    }
};

const char* TEXT_FILE_NAME = "text_output.txt";
const char* BINARY_FILE_NAME = "binary_output";

int main() {

    // シリアライズして保存
    {
        Human human("橘美也", 16);

        // テキストで保存
        {
            ofstream text_ofs(TEXT_FILE_NAME);
            boost::archive::text_oarchive text_oa(text_ofs);
            text_oa << human;
            text_ofs.close();
        }

        // バイナリで保存
        {
            ofstream binary_ofs(BINARY_FILE_NAME);
            boost::archive::binary_oarchive binary_oa(binary_ofs);
            binary_oa << human;
            binary_ofs.close();
        }
    }
   
    // 読み込みと出力
    {
        // テキストを読み込み
        {
            Human text_human;

            ifstream text_ifs(TEXT_FILE_NAME);
            boost::archive::text_iarchive text_ia(text_ifs);
            text_ia >> text_human;
            text_ifs.close();

            cout << "テキストを読み込み" << endl;
            text_human.Print();
        }

        // バイナリを読み込み
        {
            Human binary_human;

            ifstream binary_ifs(BINARY_FILE_NAME);
            boost::archive::binary_iarchive binary_ia(binary_ifs);
            binary_ia >> binary_human;
            binary_ifs.close();

            cout << endl;
            cout << "バイナリを読み込み" << endl;
            binary_human.Print();
        }
    }
    return 0;
}

ビルド

clang++ boost_seria.cpp -lboost_serialization

出力結果

テキストを読み込み
name: 橘美也
age : 16

バイナリを読み込み
name: 橘美也
age : 16

出力ファイル

text_output.txt

22 serialization::archive 16 0 0 9 橘美也 16

所感

特に苦労することもなく、シリアライズを行うことができました。
brewとboostとインターネットは偉大ですね。

疑問点は下記の項目です。また調べます。

  • 同じインスタンスを出力したバイナリファイル(サイズ66byte)よりテキストファイル(サイズ44byte)の方が容量が小さい(テキスト > バイナリだと思っていたけどそうではない?)
  • text_output.txtの22とかの数値の意味
  • ビルド時の-lboost_serializationみたいなライブラリ名をどうやって見つけるのか。どのヘッダファイルがどのライブラリに対応しているのかを調べる方法
  • /usr/local/Cellar/とは

参考文献

boost::serializationの使い方
boost::serialization - C++でゲームプログラミング