C++でクラスをシリアライズおよびデシリアライズすることは可能ですか?
私はJavaを3年間使用していますが、その言語ではシリアライゼーション/デシリアライゼーションはかなり簡単です。 C++には同様の機能がありますか?シリアル化を処理するネイティブライブラリはありますか?
例が役立ちます。
Boost::serialization
ライブラリはこれをかなりエレガントに処理します。いくつかのプロジェクトで使用しました。使用方法を示すサンプルプログラム here があります。
それを行う唯一のネイティブな方法は、ストリームを使用することです。これは基本的にBoost::serialization
ライブラリが行うことのすべてであり、オブジェクトをテキストのような形式に書き込み、同じ形式から読み取るようにフレームワークを設定することにより、streamメソッドを拡張します。
組み込み型、またはoperator<<
とoperator>>
が適切に定義された独自の型の場合、それは非常に簡単です。詳細については、 C++ FAQ を参照してください。
これは古い投稿ですが、c++ serialization
を検索するときに最初に表示される投稿の1つです。
C++ 11にアクセスできる人は誰でも cereal をご覧になることをお勧めします。これは、C++ 11ヘッダーのみのライブラリで、バイナリ、JSON、およびXMLをそのままサポートします。 cerealは、拡張と使用が簡単になるように設計されており、Boostと同様の構文を持っています。
Boostは良い提案です。しかし、あなたがあなた自身を転がしたいと思うならば、それはそれほど難しくありません。
基本的には、オブジェクトのグラフを作成し、それらを何らかの構造化ストレージ形式(JSON、XML、YAMLなど)に出力する方法が必要です。グラフの構築は、再帰的まともなオブジェクトマーキングアルゴリズムを使用して、マークされたすべてのオブジェクトを出力するのと同じくらい簡単です。
初歩的な(しかしまだ強力な)シリアル化システムについて説明した記事を書きました。おもしろいかもしれません: SQLiteをオンディスクファイル形式として使用する、パート2 。
Boost :: serialization は素晴らしいオプションですが、新しいプロジェクトに遭遇しました: Cereal 私はもっとエレガントになりました!調査することを強くお勧めします。
Google プロトコルバッファ をお勧めします。新しいプロジェクトでライブラリをテストドライブする機会があり、非常に使いやすいです。ライブラリは、パフォーマンスのために大幅に最適化されています。
Protobufは、オブジェクトをシリアル化するのではなく、仕様に従ってシリアル化されたオブジェクトのコードを生成するという意味で、ここで説明した他のシリアル化ソリューションとは異なります。
「組み込み」ライブラリに関する限り、<<
と>>
はシリアル化専用に予約されています。
<<
をオーバーライドして、オブジェクトをシリアル化コンテキスト(通常はiostream
)に出力し、>>
をオーバーライドして、そのコンテキストからデータを読み取ります。各オブジェクトは、集約された子オブジェクトを出力します。
オブジェクトグラフにサイクルが含まれていない限り、この方法は正常に機能します。
その場合、ライブラリを使用してこれらのサイクルを処理する必要があります。
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の両方のコーデックがありますが、興味深い部分は、名前と値のペアの形式でオブジェクトクラス表現を保持できることです。要件に応じてベースライブラリを変更しました。これがお役に立てば幸いです。
他のポスターで説明されているように、ブーストシリアル化の使用をお勧めします。ブーストチュートリアルをうまく補完する、使用方法に関する詳細なチュートリアルを次に示します。 http://www.ocoudert.com/blog/2011/07/09/a-practical-guide-to-c-シリアル化/
Sweet Persist は別のものです。
XML、JSON、Lua、およびバイナリ形式のストリームとの間でシリアル化することが可能です。
シンプルで最高のパフォーマンスが必要で、データの後方互換性を気にしない場合は、 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);