C ++ повышает сериализацию подкласса указателем базового класса - PullRequest
0 голосов
/ 04 июля 2018

Я выполняю сериализацию / десериализацию объекта подкласса по указателю на его базовый класс. Все работает хорошо, но я упускаю одну особенность: добавление параметра времени выполнения в конструктор десериализованного объекта, пример:

class Base {  
public:  
    Base(AnotherClass* another)  
        :m_another(another)  
    {}  
protected:  
    AnotherClass* m_another;  
};  
class Derived : public Base {  
public:  
    Derived(AnotherClass* another)  
        :Base(another)  
    {}  
    Derived()  
        :Base(nullptr)  
    {}  
private:  
    /* different other members */  
};  
BOOST_CLASS_EXPORT(Derived);  
...  

Мой обычный способ создания производного объекта:

Base* obj = new Derived(anotherObj);  

Десериализация происходит так:

Base* obj;
ar >> obj;  

Будет вызван конструктор по умолчанию (Derived ()), и десериализация продолжается, НО m_another не десериализован, его следует передать конструктору, все остальные поля десериализовать.
Более того, я не могу установить m_another после десериализации, потому что это действительно влияет на десериализацию.
Я могу передать ссылку на anotherObj через глобальную переменную - безобразно, но работает.
Есть ли способ решить это не так безобразно?

1 Ответ

0 голосов
/ 04 июля 2018

Прежде всего, чтобы получить полиморфное поведение класса, вам нужен полиморфный тип . Это логическое требование указано в документации :

Оказывается, что сериализованный тип объекта зависит от того, является ли базовый класс (в данном случае базовым) полимофическим или нет. Если база не является полиморфной, то есть если у нее нет виртуальных функций, то объект типа base будет сериализован. Информация в любых производных классах будет потеряна. Если это то, что нужно (обычно это не так) , тогда никаких других усилий не требуется.

Если базовый класс является полиморфным , объект самого производного типа (в данном случае производный_данный или производный_два) будет сериализован. Вопрос о том, какой тип объекта должен быть сериализован, (почти) автоматически решается библиотекой.

[...]

Очевидный способ обеспечить это - использовать виртуальный деструктор ( Когда использовать виртуальные деструкторы? ).


Далее, чтобы (де) сериализовать типы, используя конструктор не по умолчанию, используйте save_construct_data / load_construct_data. Опять же, документы - хорошее начало.

...