1

マップをファイルにシリアル化する必要があります。最初にマップをバイトバッファに入れ、次にバイトバッファをファイルに書き込みます。load メソッドでは、最初にファイル全体を bytebuffer に読み込み、次に bytebuffer からマップを埋めます。現在、私はこのコードを持っています(ファイル処理なし):

保存方法:

map<int, BaseClass*> myMap;
map<int, BaseClass*>::iterator it;
ByteBuffer bb;

bb.putUInt(myMap.size());
for (it = myMap.begin(); it!= myMap.end(); it++){
  bb.putUInt(it->first);
  it->second->save(bb); // the save method put the static type first, then the data
}

ロード方法

...// get the map size from bb
for (int i=0; i<size; i++){
  int key = bb.getUInt() // in the real code there isn't signed/unsigned mismatch
  BaseClass* value = MyFactory.create(bb) // detailed later
  myMap.insert(key,value);
}

MyFactory.create:

BaseClass* MyFactory::create( ByteBuffer& bb){
  TypeEnum type = static_cast<TypeEnum>(bb.getUInt());
  BaseClass* value;

  switch (type){
    case DerivedClass1:
      value = new DerivedClass1()
      break;

    case DerivedClass2:
      value = new DerivedClass2()
      break;

    // etc...
  }

  value->load(bb);
  return value;
}

このソリューションでは、大きな列挙型 TypeEnum、長いスイッチがあり、基本クラスからの新しい派生クラスごとにそれらを増やす必要があります。これを行うより良い方法はありますか?

4

2 に答える 2

1

あなたのアプローチは正しいと思います。ただし、次の改善を検討することをお勧めします。

factory::create 内でスマート ポインターを使用します。今は例外安全ではないため:

    std::auto_ptr<BaseClass> MyFactory::create(ByteBuffer& bb)
    {
        TypeEnum type = static_cast<TypeEnum>(bb.getUInt());
        std::auto_ptr < BaseClass > value;
        switch (type)
        {
            case DerivedClass1:
                value.reset(new DerivedClass1());
                break;
            case DerivedClass2:
                value.reset(new DerivedClass2());
                break;
        }
        value->load(bb);
        return value;
    }

このようにして、ロードに失敗してもメモリ リークは発生しません。

于 2012-09-18T09:19:57.060 に答える
1

あなたの代わりに、Boost.Serializationライブラリの使用を検討します。

于 2012-09-18T09:25:52.550 に答える