C でオブジェクトのシリアル化の必要性に直面したとき、多くの人はクラス ID ベースのスイッチングを伴うよく知られたパターンに頼ります。 :
<code class="cpp">class Serializable { public: static Serializable *deserialize(istream &is) { int id; is >> id; switch(id) { case EXAMPLE_ID: return new ExampleClass(is); //... } } void serialize(ostream &os) { os << getClassID(); serializeMe(os); } protected: int getClassID()=0; void serializeMe(ostream &os)=0; };
このアプローチは直感的に見えるかもしれませんが、潜在的な落とし穴があります:
ファクトリー パターン アプローチ
よりエレガントで拡張可能な解決策は、ファクトリ パターンを使用することです。ファクトリ クラスは、クラス ID に依存するのではなく、登録されたキーと機能のペアのセットに基づいてオブジェクトを作成します。関数は、対応するクラスのインスタンスを返します。
<code class="cpp">template<typename K, typename T> class Factory { typedef T *(*CreateObjectFunc)(); std::map<K, CreateObjectFunc> mObjectCreator; template<typename S> static T* createObject(){ return new S(); } template<typename S> void registerClass(K id){ mObjectCreator.insert( std::make_pair<K,CreateObjectFunc>(id, &createObject<S> ) ); } T* createObject(K id){ typename std::map<K, CreateObjectFunc>::iterator iter = mObjectCreator.find(id); if (iter == mObjectCreator.end()){ return NULL; } return ((*iter).second)(); } };</code>
この実装では、対象の各クラスがファクトリに登録され、そのクラス ID が作成関数に関連付けられます。オブジェクトを逆シリアル化する場合、ファクトリに対応するクラス ID が照会されます。見つかった場合、作成関数が呼び出され、オブジェクトがインスタンス化されます。
以上がファクトリ パターンを使用して C でクラスをストリームにエレガントにシリアル化する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。