2016-08-25 11 views
-1

私は、複数のソース、つまりソース1とソース2からなることができる自分のオブジェクトのシリアライゼーションを作成しようとしていますが、スキーマ処理は両方でかなりうんざりしています。だから、私は円滑なシリアライゼーションを処理しようとしています。複数のソースと異なるスキーマからオブジェクトをシリアル化する円滑な方法はありますか?

void CSerFoo::Serialize(CArchive& ar) 
{ 
    try 
    { 
     //ar.Flush(); 
     SerializeEx(ar); // For the Serialization of the Good Ones, from the point now on 
    } 
    catch(...) // If the Object cannot be Serialized using the above Method try the Next way to decode 
    { 
     try 
     { 
      //ar.Flush(); 
      SpecialSerialize1(ar); // For the Serialization of the Objects from the Source 1, actually code from the Source 1 
     } 
     catch(...) // If the Object cannot be Serialized using the above Method try the Last way to decode 
     { 
      try 
      { 
       //ar.Flush(); 
       SpecialSerialize2(ar); // For the Serialization of the Objects from the Source 2, actually code from the Source 2 
      } 
      catch(...) 
      { 
       // No way 
      } 
     } 
    } 
} 

EDIT 1:

このソースからのシリアルコード1

// From Source 1 
IMPLEMENT_SERIAL(CSerFoo, CObject, VERSIONABLE_SCHEMA | 3) 
void CSerFoo::Serialize(CArchive& ar) // This will be the Consolidated CSerFoo's SpecialSerialize1 
{ 
    UINT uiSchema = ar.GetObjectSchema(); 
    if (ar.IsStoring()) 
    { 
     ar << m_sName;       
     ar << m_sDesc; 
     ar << m_String1; 

     ar << m_fValue1; 
     ar << m_fValue2; 

     ar << m_iValue1; 
     ar << m_iValue2; 

     ar << m_String2; 
     ar << m_String3; 

    } 
    else 
    { 
     ar >> m_sName;       
     ar >> m_sDesc; 
     ar >> m_String1; 

     if(uischema > 0)// Added in VERSION_SCHEMA 1 
     { 
      ar >> m_fValue1; 
      ar >> m_fValue2; 
     } 

     if(uischema > 1) // Added in VERSION_SCHEMA 2 
     { 
      ar >> m_iValue1; 
      ar >> m_iValue2; 
      ar >> m_String4; 
     } 

     if(uischema > 2) // Added in VERSION_SCHEMA 3 
     { 
      ar >> m_String2; 
      ar >> m_String3; 
     } 
    } 
} 

これでシリアルコードは、ソースからのもので今2

// From Source 2 
IMPLEMENT_SERIAL(CSerFoo, CObject, VERSIONABLE_SCHEMA | 3) 
void CSerFoo::Serialize(CArchive& ar) // This will be the Consolidated CSerFoo's SpecialSerialize2 
{ 
    UINT uiSchema = ar.GetObjectSchema(); 
    if (ar.IsStoring()) 
    { 
     ar << m_sName;       
     ar << m_sDesc; 
     ar << m_String1; 

     ar << m_fValue1; 

     ar << m_fValue2; 
     ar << m_iValue1; 
     ar << m_iValue2; 

     ar << m_iValue3; 
     ar << m_String2; 
     ar << m_String3; 

    } 
    else 
    { 
     ar >> m_sName;       
     ar >> m_sDesc; 
     ar >> m_String1; 

     if(uischema > 0)// Added in VERSION_SCHEMA 1 
     { 
      ar >> m_fValue1; 

     } 

     if(uischema > 1) // Added in VERSION_SCHEMA 2 
     { 
      ar >> m_fValue2; 
      ar >> m_iValue1; 
      ar >> m_iValue2; 
     } 

     if(uischema > 2) // Added in VERSION_SCHEMA 3 
     { 
      ar >> m_iValue3; 
      ar >> m_String2; 
      ar >> m_String3; 
     } 
    } 
    // m_String4 is not there in the Source 2 
} 

連結CSerFoo(から今では)両方のソースからすべてのフィールドを持っています。 CSerFooの同じオブジェクトのシリアライゼーション。私たちは別のクラスを作ることについて妥協することはできません。

問題私が直面している問題は、後続のシリアル化の呼び出しでカーソル(CArchive :: m_lpBufCur)が移動され、次のシリアライズの試みが失敗することです。

これを達成する方法はありますか?

何か不足していますか?

ありがとうございました!

+1

SerializeExとSpecialSerializeXが何をしているのかわからなければ、これについて何も言い難いです。 –

+0

これは、シーケンス内のint、floatおよびstringのシリアル化だけです。シーケンスとフィールドの数は、シリアル化ごとに異なる場合があります。つまり、問題の内容です。 –

+0

バージョン管理可能なスキーマを使用する場合は問題ありません。また、バージョン管理可能なスキーマが、お客様が作成した問題の標準的な解決方法です。短い紹介と[TN002:Persistent Object Data Format](https:// msdn)と同様に[CArchive :: GetObjectSchema](https://msdn.microsoft.com/en-us/library/wkbc2za4.aspx)を参照してください。 .microsoft.com/ja-jp/library/32wxt301.aspx)を参照してください。とにかく、尋ねられたように、質問は答えられません。私たちが共通の基盤を持つように[mcve]を提供してください。 – IInspectable

答えて

1

strong exepction safety guaranteeがない場合、例外を解決する方法が間違っているようです。

ですから、彼らはそれを付着ような機能を実装することができ

を(のみCArchiveオブジェクトの内部に1が好きか、関数の中にそれをコピーしていない機能でローカルオフセットを使用して)しかし、また、例外は次のように虐待されているように思えますここで構造を制御する。あなたは多分これがクリーンなコードのように私には思えるし、例外を「乱用」しない唯一の「例外」の状況に例外を使用することを検討して

if(isFormat1Convertible(ar)) 
{ 
    SerializeEx(ar); 
} 
else if(isFormat2Convertible(ar)) 
{ 
    SpecialSerialize1(ar); 
} 
... 

のようないくつかの機能を持っている必要があります。

+0

[シリアル化のMFC](https://msdn.microsoft.com/en-us/library/6bz744w8.aspx)を理解していない人によって書かれた粗kludge。例外については、関数が約束を守らないと投げられるべきです。それが致命的(または「例外的」*)かどうかは、クライアントコードが決定するかどうかです。一般に、例外をスローするコードは、この失敗が文脈で致命的であるかどうかはほとんど知りません。 – IInspectable

+0

はい、これは "MFC"のやり方ではありませんが、言語の代わりに言語/フレームワークをプログラミングする方が好きです(これについては、第4章の「コードの完了」を参照してください)。また、インターネット上でのいくつかの議論がありますが、OPでのこの例外の使用を "コードの匂い"と見なしています(OPには、それ以外にも投稿が存在しないいくつかの問題があります)。私はしばらくの間、MFCを使用していないが、私はdocuから見ると、 "VERSIONABLE_SCHEMA"と呼ばれるものがある。これは、例外(または他の方法ではなく、状況に応じて)の代わりに正しい形式を選択するために使用される可能性があります。 – Hayt

+0

あなたはそれをプログラムするかどうかにかかわらず、教育的な意思決定を下すためのフレームワークを知る必要があります。 * Code Complete *のアドバイスには根拠があります。あなたの洞察力の欠如は、それを適用することを奪う。また、MFCのシリアル化を変更してルールを破らない限り、MFCのシリアライゼーションにプログラムすることはできません。 – IInspectable

関連する問題