Я столкнулся с той же проблемой, что и вы! Поэтому я просмотрел документ boost, который дает способ решить проблему, я могу определить класс D для управления производными объектами и использовать ar.register_type
для сравнения класса abc, точно так же, как это :
class base {
...
};
class derived_one : public base {
...
};
class derived_two : public base {
...
};
main(){
...
base *b;
...
ar & b;
}
При сохранении b какой объект должен быть сохранен? При загрузке b какой объект должен быть создан? Должен ли это быть объект класса производный_один, производный_два или, может быть, базовый?
Оказывается, тип сериализуемого объекта зависит от того, является ли базовый класс (в данном случае base) полиморфным или нет. Если база не полиморфна, то есть не имеет виртуальных функций, то будет сериализован объект типа база. Информация в любых производных классах будет потеряна. Если это то, что нужно (обычно это не так), то никаких других усилий не требуется.
Если базовый класс является полиморфным, будет сериализован объект наиболее производного типа (в данном случае производный_один или производный_два). Вопрос о том, какой тип объекта должен быть сериализован, (почти) автоматически обрабатывается библиотекой.
Система «регистрирует» каждый класс в архиве при первой сериализации объекта этого класса и присваивает ему порядковый номер. В следующий раз, когда объект этого класса сериализуется в том же архиве, этот номер записывается в архив. Таким образом, каждый класс однозначно идентифицируется в архиве. Когда архив считывается обратно, каждый новый порядковый номер повторно связывается с читаемым классом. Обратите внимание, что это означает, что «регистрация» должна происходить как во время сохранения, так и во время загрузки, чтобы таблица целочисленного класса, построенная при загрузке, была идентична таблице целочисленного класса, построенной при сохранении. Фактически, ключ ко всей системе сериализации заключается в том, что вещи всегда сохраняются и загружаются в одной и той же последовательности. Это включает в себя «регистрацию».
main(){
derived_one d1;
derived_two d2:
...
ar & d1;
ar & d2;
// A side effect of serialization of objects d1 and d2 is that
// the classes derived_one and derived_two become known to the archive.
// So subsequent serialization of those classes by base pointer works
// without any special considerations.
base *b;
...
ar & b;
}
Когда b читается, ему предшествует уникальный (для архива) идентификатор класса, который ранее был связан с классом производный_один или производный_два.
Если производный класс НЕ был автоматически "зарегистрирован", как описано выше, при вызове сериализации будет выдано исключение unregistered_class.
Это можно решить, явно зарегистрировав производный класс. Все архивы являются производными от базового класса, который реализует следующий шаблон:
template<class T>
register_type();
Таким образом, нашу проблему можно было бы также решить, написав:
main(){
...
ar.template register_type<derived_one>();
ar.template register_type<derived_two>();
base *b;
...
ar & b;
}
Обратите внимание, что если функция сериализации разделена между сохранением и загрузкой, обе функции должны включать регистрацию. Это необходимо для синхронизации сохранения и соответствующей загрузки.
вы также можете использовать:
#include <boost/serialization/export.hpp>
...
BOOST_CLASS_EXPORT_GUID(derived_one, "derived_one")
BOOST_CLASS_EXPORT_GUID(derived_two, "derived_two")
main(){
...
base *b;
...
ar & b;
} Макрос BOOST_CLASS_EXPORT_GUID связывает строковый литерал с классом. В приведенном выше примере мы использовали строковый рендеринг имени класса. Если объект такого «экспортируемого» класса сериализуется через указатель и не регистрируется иным образом, строка «экспорт» включается в архив. При последующем чтении архива строковый литерал используется для поиска класса, который должен быть создан библиотекой сериализации. Это позволяет каждому классу находиться в отдельном заголовочном файле вместе с его строковым идентификатором. Нет необходимости поддерживать отдельную «предварительную регистрацию» производных классов, которые могут быть сериализованы. Этот метод регистрации называется «экспортом ключа».
Может быть полезно для вас!! подробности вы можете увидеть здесь:http://www.boost.org/doc/libs/1_54_0/libs/serialization/doc/index.html
person
minicaptain
schedule
15.07.2013