C++ でのコード生成の大きな用途の 1 つは、メッセージのシリアル化をサポートすることです。通常、同じステップでメッセージのコンテンツとレイアウトの指定をサポートし、通信ストリームとの間でシリアル化できるオブジェクトを提供できるそのメッセージ タイプのコードを生成します。これまでは、通常、次のようなコードが生成されていました。
class MyMessage : public SerialisableObject
{
// message members
int myNumber_;
std::string myString_;
std::vector<MyOtherSerialisableObject> aBunchOfThingsIWantToSerialise_;
public:
// ctor, dtor, accesors, mutators, then:
virtual void Serialise(SerialisationStream & stream)
{
stream & myNumber_;
stream & myString_;
stream & aBunchOfThingsIWantToSerialise_;
}
};
この種の設計を使用する際の問題は、優れたアーキテクチャの重要なルールに違反することです。つまり、設計の意図を 2 回指定する必要はありません。重複したコードやその他の一般的な開発の重複など、意図の重複により、コード内の 1 つの場所が他の場所と発散する余地が生じ、エラーが発生します。
上記では、複製はメンバーのリストです。潜在的なエラーには、メンバーをクラスに追加したが、それをシリアライゼーション リストに追加するのを忘れている、メンバーを 2 回シリアライズしている (メンバー宣言と同じ順序を使用していない、または同様のメンバーのスペル ミスが原因である可能性があります) などがあります。 、またはメンバーではないものをシリアル化します (名前の検索で、検索規則に一致するオブジェクトとは異なるスコープで何かが見つからない限り、コンパイラ エラーが発生する可能性があります)。この種の間違いは、すべてのヒープ割り当てを (スマート ポインターを使用する代わりに) 削除と一致させたり、(RAII ctor//dtor メカニズムを使用して) ファイルを閉じて開いたりすることをもはや試みないのと同じ理由です。
したがって、一般的に、これはコード生成で処理できるものの 1 つです。ファイル MyMessage.cg を作成して、レイアウトとメンバーの両方を 1 つのステップで指定することができます。
serialisable MyMessage
{
int myNumber_;
std::string myString_;
std::vector<MyOtherSerialisableObject> aBunchOfThingsIWantToSerialise_;
};
コード生成ユーティリティを介して実行され、コードが生成されます。
外部コード生成なしで c++0x でこれを行うことがまだ可能かどうか疑問に思っていました。クラスを一度シリアライズ可能として指定できるようにする新しい言語メカニズムはありますか?そのメンバーの名前とレイアウトは、シリアライズ中にメッセージをレイアウトするために使用されますか?
明確にするために言うと、c++0x より前の言語でも、この種の動作に近づくことができるブースト タプルとフュージョンのトリックがあることを私は知っています。ただし、これらの使用法は、メンバー名によるアクセスではなくタプルへのインデックス付けに基づいているため、メッセージにアクセスするコード内の他の場所も並べ替える必要があるため、レイアウトを変更することはすべて脆弱です。メッセージを使用するコード内の場所でレイアウト仕様を複製する必要がないように、ある種のメンバー名によるアクセスが必要です。
また、これを次のレベルに引き上げて、一部のメンバーをいつシリアライズしてはならないかを指定するように依頼するとよいかもしれません。組み込みのシリアライゼーションを提供する他の言語は、多くの場合、これを行うための何らかの属性を提供します。自然に見えるかもしれません。ただし、メッセージの有効期間は、他のデータの有効期間とは別に、通信レイヤーとの間のトランスポートにあるため、すべてがシリアル化されていないシリアル化可能なオブジェクトを持つのは悪い設計だと個人的には思います。また、そのメンバーのように純粋にシリアライズ可能なオブジェクトを持つこともできます。そのため、そのような機能は、言語がまだ提供していないものではありません。
これは可能ですか?それとも、標準化委員会はこの種の内省機能を除外したのでしょうか? 上記のコード gen ファイルのようにする必要はありません。コンパイル時にレイアウトとメンバーを 1 つのステップで指定する簡単な方法を使用すれば、この一般的な問題を解決できます。