Как работает чтение объектов из архива наддува, которые были сохранены с помощью указателей на базовый класс? - PullRequest
2 голосов
/ 29 августа 2011

Я пытаюсь понять, как boost обрабатывает сериализацию объектов, которые хранятся через указатели на базовый класс. Особенно, как работает последующее чтение из созданного таким образом архива. Вот пример кода (без включения всех заголовков):

class A
{
  public:
    A() {};
    ~A() {};
    virtual void dummy() {};
  private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version) {};
};

class B : public A
{
  public:
    B() : x(0) {};
    B( int _x ) : x(_x) {};
    ~B() {};
    void dummy() {}; 
    int x;
  private:
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
      ar & boost::serialization::base_object<A>(*this);
      ar & x;
    }
};

BOOST_CLASS_EXPORT( B )
BOOST_CLASS_IMPLEMENTATION( B, boost::serialization::object_serializable)
BOOST_CLASS_TRACKING( B, boost::serialization::track_never)

int main(int argc, char *argv[])
{
  { //writing the archive
    boost::filesystem::ofstream file( "archive.dat", std::ios::trunc );
    boost::archive::text_oarchive archive( file );

    A* ptr = new B(3);
    archive & ptr;
  }

  { // reading the archive
    boost::filesystem::ifstream file( "archive.dat" );
    boost::archive::text_iarchive archive( file );

    /** What is supposed to go here? */
  }

  return 0;
}

Я понял, что

A* ptr;
archive & ptr;

так или иначе, кажется, делает работу для секции считывания. Но как это работает? Создает ли он сначала объект типа B в куче с помощью стандартного конструктора (как это, по-видимому, требуется), а затем устанавливает значения внутренних членов?

Есть ли альтернативы? Например, можно ли напрямую создать экземпляр объекта типа B из архива, если я знаю, что в архиве содержатся только объекты типа B (хотя и сериализуются с помощью указателей базового класса)?

1 Ответ

0 голосов
/ 30 августа 2011

Я считаю, что это отработка частичной специализации шаблонов для типов указателей. Где-то в boost что-то в этом роде:

class text_oarchive {
    template <class T> operator&(T);
};

и есть специализация:

template <class T*>
text_oarchive<T*>::operator&(T *t) {
    //serial the value as a pointer
}

Вы можете проверить, создает ли он копию B в куче, создав класс без конструктора по умолчанию.

...