Как мне избежать включения заголовков каждого класса, который нужно сериализовать в BOOST? - PullRequest
1 голос
/ 03 апреля 2011

У меня следующая ситуация (упрощенно):

ах:

#include <boost/serialisation/serialisation.hpp>
class B;
using namespace std; using namespace boost;
class A {
   B *b;
   template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & b; }
};

чч:

#include <boost/serialisation/serialisation.hpp>
class C;
using namespace std; using namespace boost;
class B {
   C *c;
   template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & c; }
};

ч:

#include <boost/serialisation/serialisation.hpp>
using namespace std; using namespace boost;
class C {
   int somevar;
   template<class Archive> void serialize(Archive & ar, const unsigned int version) { ar & somevar; }
};

main.cxx:

#include <boost/archive/text_oarchive.hpp>
#include <fstream>
#include "a.h"
#include "b.h"
#include "c.h"
using namespace std; using namespace boost;

int main() {
   A a; // Create the object

   ofstream ofs("save");
   archive::text_oarchive oa(ofs);

   oa << a; // Save the object

   return 0;
}

Теперь проблема в том, что мне нужно включить заголовочные файлы всех классов, которые я хочу сериализовать, в функцию сохранения (в данном случае прямо внутри main).Проблема в том, что существует более трех классов, и они намного сложнее, что приводит к узкому месту компиляции на этом этапе.

Я только недавно начал использовать сериализацию Boost, но я посмотрелпо документации и поиска в Google и здесь, так что я думаю, что я упустил что-то очевидное.

Есть ли у кого-нибудь решение для этого так, что нужно включить только "ах", а не "бх","ch" и т. д.

РЕДАКТИРОВАТЬ: Надеемся, что это важная часть ошибки компиляции, которая возникает, если я закомментирую строки #include "bh" и "ch":

main.cxx:17:1:   instantiated from here
/usr/include/boost/type_traits/is_abstract.hpp:72:4: error: incomplete type ‘B’ not allowed

Ответы [ 3 ]

3 голосов
/ 03 апреля 2011

Я думаю, что вы могли бы использовать явную реализацию, а затем определить ваши функции-члены сериализации в файлах .cpp. Тогда a.cpp может включать b.h и c.h по мере необходимости, и пользователям a.h больше не нужно это делать.

Посмотрите примеры pimpl-idiom http://www.boost.org/doc/libs/1_46_1/libs/serialization/example/demo_pimpl_A.hpp (заголовок) и http://www.boost.org/doc/libs/1_46_1/libs/serialization/example/demo_pimpl_A.cpp (исходный файл), как это сделать.

0 голосов
/ 03 апреля 2011

Прежде всего, если существует метод, любой метод, которому требуется доступ к A, B и C, просто нет другого способа, кроме как сделать A, B и C видимыми для этого метода.и в любом случае означает включение всех 3 заголовочных файлов.Таким образом, проблема с компилятором, о которой вы говорите, не может быть решена.

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

  //header myserialization.h
#include "a.h"
#include "b.h"
#include "c.h"

template<class Archive>
void serialize(Archive & ar, const unsigned int version, A& a) { ar & a.*b; }

template<class Archive>
void serialize(Archive & ar, const unsigned int version, B& b) { ar & b.*c; }

template<class Archive>
void serialize(Archive & ar, const unsigned int version, C& c) { ar & c.somevar; }
0 голосов
/ 03 апреля 2011

Отказ от ответственности: я ничего не знаю о буст-сериализации.

Поскольку у вас есть функции-члены шаблона serialize, которые должны иметь встроенные определения, использующие элементы, вы должны #include файлы заголовков для этих элементов вместо простого объявления, например, class B;.

Это будет означать, что main будет иметь значение #include "a.h" только в main, и вы не должны получать ошибки компилятора.

...