web-dev-qa-db-ja.com

C ++でクラスをシリアライズおよびデシリアライズすることは可能ですか?

C++でクラスをシリアライズおよびデシリアライズすることは可能ですか?

私はJavaを3年間使用していますが、その言語ではシリアライゼーション/デシリアライゼーションはかなり簡単です。 C++には同様の機能がありますか?シリアル化を処理するネイティブライブラリはありますか?

例が役立ちます。

130
Agusti-N

Boost::serialization ライブラリはこれをかなりエレガントに処理します。いくつかのプロジェクトで使用しました。使用方法を示すサンプルプログラム here があります。

それを行う唯一のネイティブな方法は、ストリームを使用することです。これは基本的にBoost::serializationライブラリが行うことのすべてであり、オブジェクトをテキストのような形式に書き込み、同じ形式から読み取るようにフレームワークを設定することにより、streamメソッドを拡張します。

組み込み型、またはoperator<<operator>>が適切に定義された独自の型の場合、それは非常に簡単です。詳細については、 C++ FAQ を参照してください。

90
Head Geek

これは古い投稿ですが、c++ serializationを検索するときに最初に表示される投稿の1つです。

C++ 11にアクセスできる人は誰でも cereal をご覧になることをお勧めします。これは、C++ 11ヘッダーのみのライブラリで、バイナリ、JSON、およびXMLをそのままサポートします。 cerealは、拡張と使用が簡単になるように設計されており、Boostと同様の構文を持っています。

47
Azoth

Boostは良い提案です。しかし、あなたがあなた自身を転がしたいと思うならば、それはそれほど難しくありません。

基本的には、オブジェクトのグラフを作成し、それらを何らかの構造化ストレージ形式(JSON、XML、YAMLなど)に出力する方法が必要です。グラフの構築は、再帰的まともなオブジェクトマーキングアルゴリズムを使用して、マークされたすべてのオブジェクトを出力するのと同じくらい簡単です。

初歩的な(しかしまだ強力な)シリアル化システムについて説明した記事を書きました。おもしろいかもしれません: SQLiteをオンディスクファイル形式として使用する、パート2

16
Frank Krueger

Boost :: serialization は素晴らしいオプションですが、新しいプロジェクトに遭遇しました: Cereal 私はもっとエレガントになりました!調査することを強くお勧めします。

13
M2tM

Google プロトコルバッファ をお勧めします。新しいプロジェクトでライブラリをテストドライブする機会があり、非常に使いやすいです。ライブラリは、パフォーマンスのために大幅に最適化されています。

Protobufは、オブジェクトをシリアル化するのではなく、仕様に従ってシリアル化されたオブジェクトのコードを生成するという意味で、ここで説明した他のシリアル化ソリューションとは異なります。

13
yoav.aviram

「組み込み」ライブラリに関する限り、<<>>はシリアル化専用に予約されています。

<<をオーバーライドして、オブジェクトをシリアル化コンテキスト(通常はiostream)に出力し、>>をオーバーライドして、そのコンテキストからデータを読み取ります。各オブジェクトは、集約された子オブジェクトを出力します。

オブジェクトグラフにサイクルが含まれていない限り、この方法は正常に機能します。

その場合、ライブラリを使用してこれらのサイクルを処理する必要があります。

12
Frank Krueger

amef プロトコルを確認できます。amefでのC++エンコーディングの例は次のようになります。

    //Create a new AMEF object
    AMEFObject *object = new AMEFObject();

    //Add a child string object
    object->addPacket("This is the Automated Message Exchange Format Object property!!","adasd");   

    //Add a child integer object
    object->addPacket(21213);

    //Add a child boolean object
    object->addPacket(true);

    AMEFObject *object2 = new AMEFObject();
    string j = "This is the property of a nested Automated Message Exchange Format Object";
    object2->addPacket(j);
    object2->addPacket(134123);
    object2->addPacket(false);

    //Add a child character object
    object2->addPacket('d');

    //Add a child AMEF Object
    object->addPacket(object2);

    //Encode the AMEF obejct
    string str = new AMEFEncoder()->encode(object,false);

Javaでのデコードは次のようになります。

    string arr = amef encoded byte array value;
    AMEFDecoder decoder = new AMEFDecoder()
    AMEFObject object1 = AMEFDecoder.decode(arr,true);

プロトコルの実装にはC++とJavaの両方のコーデックがありますが、興味深い部分は、名前と値のペアの形式でオブジェクトクラス表現を保持できることです。要件に応じてベースライブラリを変更しました。これがお役に立てば幸いです。

4
Dave

他のポスターで説明されているように、ブーストシリアル化の使用をお勧めします。ブーストチュートリアルをうまく補完する、使用方法に関する詳細なチュートリアルを次に示します。 http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-シリアル化/

3
jbat100

Sweet Persist は別のものです。

XML、JSON、Lua、およびバイナリ形式のストリームとの間でシリアル化することが可能です。

3
Vincent

シリアル化の基礎としてよく使用される抽象ファクトリーを調べることをお勧めします

C++ファクトリーに関する別のSO質問で回答しました。柔軟なファクトリに関心がある場合は、 there を参照してください。私は、ET ++からマクロを使用するための古い方法を説明しようとしていますが、これは私にとって非常に効果的です。

ET ++ は、古いMacAppをC++およびX11に移植するプロジェクトでした。その努力の中で、エリック・ガンマなどはデザインパターンについて考え始めました。 ET ++には、実行時のシリアル化とイントロスペクションの自動方法が含まれていました。

2
epatel

シンプルで最高のパフォーマンスが必要で、データの後方互換性を気にしない場合は、 HPS を試してください。軽量で、Boostよりもはるかに高速で、Protobufなどよりもはるかに使いやすいです.

例:

std::vector<int> data({22, 333, -4444});
std::string serialized = hps::serialize_to_string(data);
auto parsed = hps::parse_from_string<std::vector<int>>(serialized);
0
streaver91