【问题标题】:How do I avoid including the headers of every class that needs to be BOOST serialised?如何避免包含需要 BOOST 序列化的每个类的标题?
【发布时间】:2011-04-03 05:32:44
【问题描述】:

我有以下情况(简体):

啊哈:

#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; }
};

b.h:

#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; }
};

c.h:

#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 和 here 上进行了搜索,所以我认为我错过了一些明显的东西。

有没有人对此有解决方案,只需要包含“a.h”而不是“b.h”、“c.h”等?

编辑:如果我注释掉#include "b.h" 和 "c.h" 行,这可能是编译错误的关键部分:

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

【问题讨论】:

  • btw - 不要将 using namespace std;using namespace boost; 放在头文件中 - 您可以将其放在“cxx”文件中,然后根据需要使用 std:: 限定符头文件。
  • @quamrana:谢谢你的建议;但我只是将这个例子拼凑起来,以说明我遇到的问题。对此有什么想法吗? :P

标签: c++ serialization boost include


【解决方案1】:

我认为您可以使用显式实例化,然后在 .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(源文件)了解如何执行此操作。

【讨论】:

  • 不过,问题不在于链接;这是编译。我会发布输出,但它有几百行。我将用我希望是关键错误的内容更新问题。
  • 哦等等。我想我现在明白了。我刚发烧,脑子不太好;对不起。但是,即使我确实移动了序列化函数的定义,那不只是将错误/瓶颈从 main.o 移动到 a.o 吗?我遇到了同样的错误,但现在它在 a.o 中,除非 a.cxx #includes "b.h" 和 "c.h"。
  • @Tim, a.cpp 知道它的依赖关系。即它知道它使用b.h。它不必包含c.h,因为B 类不再通过其序列化方式公开其依赖关系。因此,如果a.cpp 包含b.hb.cpp 包含c.h,并且您使用显式实例化并在.cpp 文件中定义序列化函数,那么一切都应该顺利,每个文件只关心它的直接依赖关系.我从来没有使用过 boost.serialization 的想法,但这听起来应该可行。还要考虑@stijn 的想法,这使得main 只包含myserial.h
【解决方案2】:

免责声明:我对 boost 序列化一无所知。

由于您有模板成员函数serialize,它必须具有使用成员的内联定义,您应该#include 这些成员的头文件,而不是仅仅声明例如class B;

这意味着 main 只需要 #include "a.h" 在 main 中,您不应该得到编译器错误。

【讨论】:

  • 正如我对 Johannes Schaub 所说,这似乎只是将瓶颈/错误从 main.o 移至 a.o。我想找到一种方法(如果有的话)完全消除这个瓶颈。无论如何,感谢您的意见。
【解决方案3】:

首先,如果有一个方法,any 方法,需要访问 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; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-03
    • 1970-01-01
    • 2015-12-17
    • 1970-01-01
    相关资源
    最近更新 更多