Как сериализовать производные шаблоны классов с Boost.serialize? - PullRequest
12 голосов
/ 26 августа 2009

Я хотел бы сериализовать / десериализовать следующие классы:

class Feature{
...
virtual string str()=0;
};

template<typename T>
class GenericFeature : public Feature{
T value;
...
virtual string str();
};

Я прочитал документы boost.serialize и сказал, что вы должны регистрировать классы. Я могу зарегистрировать их в конструкторе. Но будут проблемы с загрузкой, так как регистрация будет динамической, а не статической (как я понял, классы должны быть зарегистрированы до сериализации / десериализации).

Как сохранить / загрузить классы этого типа?

1 Ответ

15 голосов
/ 26 августа 2009

Сначала скажи, что функция абстрактна, она не всегда нужна:

BOOST_SERIALIZATION_ASSUME_ABSTRACT(Feature);

Метод сериализации должен выглядеть примерно так:

template<class Archive> 
void Feature::serialize(Archive & ar, const unsigned int version)
{
   ar & BOOST_SERIALIZATION_NVP(some_member);
}


template<typename T,class Archive> 
void GenericFeature<T>::serialize(Archive & ar, const unsigned int version)
{
   ar & boost::serialization::base_object<Feature>(*this);  //serialize base class
   ar & BOOST_SERIALIZATION_NVP(some_other_member);
}

Теперь самое сложное - зарегистрировать класс в сериализации / десериализации:

boost::archive::text_iarchive inputArchive(somesstream);

boost::archive::text_oarchive outputArchive(somesstream);

//something to serialize
Feature* one = new GenericFeature<SomeType1>();
Feature* two = new GenericFeature<SomeType2>();
Feature* three = new GenericFeature<SomeType3>();

//register our class, must be all of posible template specyfication    
outputArchive.template register_type< GenericFeature<SomeType1> >();
outputArchive.template register_type< GenericFeature<SomeType2> >();
outputArchive.template register_type< GenericFeature<SomeType3> >();

// now simply serialize ;-]
outputArchive << one << two << three;

// register class in deserialization
// must be the same template specification as in serialize
// and in the same correct order or i'm get it wrong ;-D   
inputArchive.template register_type< GenericFeature<SomeType1> >();
inputArchive.template register_type< GenericFeature<SomeType2> >();
inputArchive.template register_type< GenericFeature<SomeType3> >();

Feature* another_one;
Feature* another_two;
Feature* another_three;

// and deserialize ;-]
inputArchive >> another_one >> another_two >> another_three;

Если вам нужно скрыть явную регистрацию где-нибудь и сделать ее более автоматической, есть идея сделать специальный шаблон функтора, который регистрирует один производный класс, создать все доступные и поместить в один список, чтобы один статический метод класса Feature регистрировал бы торговый центр. Однако проблема заключается в том, что вам нужна регистрация для всех версий архива, сейчас я не знаю, будет ли работать полиморфный архив или нет.

...