Я смотрел на библиотеку boost сериализации, и навязчивый способ обеспечить поддержку сериализации - определить функцию-член с подписью (упрощенно):
class ToBeSerialized {
public:
//Define this to support serialization
//Notice not virtual function!
template<class Archive>
void serialize(Archive & ar)
{.....}
};
Кроме того, один из способов поддержки сериализации базовых указателей через производный класс - это использование макроса типа:
//No mention to the base class(es) from which Derived_class inherits
BOOST_CLASS_EXPORT_GUID(Derived_class, "derived_class")
где Derived_class - это некоторый класс, который наследуется от базового класса, скажем, Base_class. Благодаря этому макросу можно сериализовать классы типа Derived_class с помощью указателей на Base_class.
Вопрос в следующем:
Я использую в C ++ для написания абстрактных фабрик, реализованных через карту из std :: string в функции (указатели), которые возвращают объекты нужного типа (и все в порядке благодаря ковариантным типам).
Однако я не вижу, как я мог бы использовать вышеупомянутую не виртуальную функцию-член сериализованного шаблона для правильной десериализации (то есть построения) объекта, не зная его типа (но предполагая, что информация о типе была сохранена сериализатором, скажем в строке).
То, что я хотел бы сделать (придерживаясь той же номенклатуры, что и выше), выглядит примерно так:
XmlArchive xmlArchive; //A type or archive
xmlArchive.open("C:/ser.txt"); //Contains type information for the serialized class
Base_class* basePtr = Factory<Base_class>::create("derived_class",xmlArchive);
с функцией на правой стороне, создающей объект в куче типа Derived_class (через конструктор по умолчанию, это часть, которую я знаю, как решить) и вызывающей функцию сериализации xmlArchive (здесь я застрял!) , т.е. сделать что-то вроде:
Base_class* Factory<Base_class>::create("derived_class",xmlArchive)
{
Base_class* basePtr = new Base_class; //OK, doable, usual map string to pointer to function
static_cast<Derived_class*>( basePtr )->serialize( xmlArchive ); //De-serialization, how?????
return basePtr;
}
Я уверен, что это можно сделать (Boost serialize делает это, но его код непроницаем!: P), но я не могу понять, как.
Ключевая проблема заключается в том, что функция сериализации является функцией шаблона. Поэтому у меня не может быть указателя на шаблонную функцию.
Поскольку цель написания шаблонной функции сериализации состоит в том, чтобы сделать код универсальным (т.е. не нужно переписывать функцию сериализации для разных архиваторов), тогда нет смысла регистрировать все производные классы для всех возможных типов архивов. , как:
MY_CLASS_REGISTER(Derived_class, XmlArchive);
MY_CLASS_REGISTER(Derived_class, TxtArchive);
...
На самом деле в моем коде я полагаюсь на перегрузку, чтобы получить правильное поведение:
void serialize( XmlArchive& archive, Derived_class& derived );
void serialize( TxtArchive& archive, Derived_class& derived );
...
Ключевым моментом, который следует иметь в виду, является то, что тип архива всегда известен, т. Е. Я никогда не использую полиморфизм времени выполнения для класса архива ... (опять же, я использую перегрузку для типа архива).
Любое предложение помочь мне?
Заранее большое спасибо!
Приветствия