IMPLEMENT_SERIALのスキーマ番号について


xyz  2006-02-24 00:42:40  No: 60805

おせわになります。

Serialize関数を保持した、
CAAAクラスとCBBBクラスがあり、
CBBBはCAAAを継承している状況で、
CAAAクラスに新たに変数を追加したいと思っています。

現在、IMPLEMENT_SERIALは以下のようになっていて、
CAAAクラスにあらたに変数を追加するということで
CAAAクラスのスキーマ番号を1から2に変更しました。

IMPLEMENT_SERIAL(CAAA , CObject , VERSIONABLE_SCHEMA|2)  ←1から2に変更
IMPLEMENT_SERIAL(CBBB , CAAA , VERSIONABLE_SCHEMA|1)

変更後、以下のCBBBクラスのシリアル化処理の中の、
CAAAクラスのSerialize関数内で
スキーマ番号をGetObjectSchema関数で取得すると
「1」となります。

//#####  CAAAクラスのシリアル化  #####
void CAAA::Serialize(CArchive& ar)
{
  if(ar.IsStoring()){
    ar  <<  m_intA
        <<  m_intB
        <<  m_intC
  }
  else{
    int Ver = ar.GetObjectSchema();
    ar  >>  m_intA
        >>  m_intB
        >>  m_intC
   if(Ver >= 2)
   {
     ar >>  m_intD;
   }
}

//#####  CBBBクラスのシリアル化  #####
void CBBB::Serialize(CArchive& ar)
{
  CAAA::Serialize(ar);

  if(ar.IsStoring()){
    ar  <<  m_dblA
  }
  else{
    ar  >>  m_dblA
  }
}

このケースで、
CAAAクラスのデータを追加したい場合、
やはり、CBBBクラスのスキーマ番号も1から2に変更しないと
いけないのでしょうか?
よろしくおねがいします。


dairygoods  2006-02-24 02:41:11  No: 60806

VC++6.0 のソースを見てみると、
派生クラスが各々でスキーマ番号を管理できる
作りにはなっていないようです。

自力でバージョン管理したほうがよさそうです。

void CAAA::Serialize(CArchive& ar)
{
  if(ar.IsStoring()){
    ar  <<  2
        <<  m_intA
        <<  m_intB
        <<  m_intC
  }
  else{
    UINT Ver;
    ar  >> Ver;
    ar  >>  m_intA
        >>  m_intB
        >>  m_intC
   if(Ver >= 2)
   {
     ar >>  m_intD;
   }
}


xyz  2006-02-24 18:52:02  No: 60807

回答ありがとうございます。

>VC++6.0 のソースを見てみると、
>派生クラスが各々でスキーマ番号を管理できる
>作りにはなっていないようです。

そうですかぁ。
それぞれのクラスで管理してくれてるものだとおもっていました。

>自力でバージョン管理したほうがよさそうです

CAAAクラスのみ存在する、EXEファイルのバージョンを既に配布済みで、
今回、機能追加の案件で、CBBBクラスを追加していますので、
CAAAクラスのシリアライズの最初に、「Ver」を追加することは、
難しいと思っています。
※EXEファイルのバージョンをみることで対処は可能とおもいますが...

対応方法としては、
今後、CBBBクラスのスキーマ番号を2とし、
どちらかで変数追加があり、スキーマ番号を追加する際は、
CAAAクラスとCBBBクラスのスキーマを同時に上げていくのが
一番シンプルなのかと思うのですがいかがでしょうか?


dairygoods  2006-02-24 19:35:08  No: 60808

> どちらかで変数追加があり、スキーマ番号を追加する際は、
> CAAAクラスとCBBBクラスのスキーマを同時に上げていくのが
> 一番シンプルなのかと思うのですがいかがでしょうか?

CAAAの変更が難しいのでしたら、そのほうがよいでしょうね。

ですが、ar.GetObjectSchema() は、一度しか呼び出せないようなので、
CAAA、CBBBともバージョン判定の必要が出てくると、
再び、すっきりしないコードになりそうです。


xyz  2006-02-24 19:58:23  No: 60809

回答ありがとうございます。

>ですが、ar.GetObjectSchema() は、一度しか呼び出せないようなので、
>CAAA、CBBBともバージョン判定の必要が出てくると、
>再び、すっきりしないコードになりそうです。

そうですかぁ。
ということは、
スキーマ番号の変数「Ver」を
CAAAクラスのメンバ変数とし、
CAAAクラスのSerialize内の読み込み処理の先頭で、
ar.GetObjectSchema() 
を行い、CBBBクラスのシリアライズの時も、
CAAAクラスのメンバ変数「Ver」を見てバージョンを判断する
ということになるのですね。

無事解決できました。
ありがとうございました。今後もよろしくおねがいします。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加