【问题标题】:Boost Serialization via base pointer to derived class [duplicate]通过指向派生类的基指针提升序列化[重复]
【发布时间】:2011-12-02 03:05:48
【问题描述】:

可能重复:
Boost Serialization using polymorphic archives

我正在尝试使用指向派生类的基指针序列化我的类,但这只会序列化基类。

我刚看了http://www.boost.org/doc/libs/1_32_0/libs/serialization/doc/special.html#registration,但是导出宏和注册函数似乎都没有改变任何东西。

考虑以下非常基本的类层次结构:

#include <iostream>
#include <fstream>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>

class A
{
private:
  friend class boost::serialization::access;
  template <typename Archive>
  void serialize(Archive& ar, const unsigned int version)
  { 
    std::cout << "A!\n";
  }
};

class B : public A
{
private:
  friend class boost::serialization::access;
  template <typename Archive>
  void serialize(Archive& ar, const unsigned int version)
  {
    ar & boost::serialization::base_object<A>(*this);
    std::cout << "B!\n";
  }
};

int main()
{
  std::ofstream of("mybin.bin");
  boost::archive::binary_oarchive oa(of);

  A* b = new B();
  oa << b;

  delete b;

  return 0;
}

输出将是:

啊!

显然,我正在寻找的输出是 A!乙!有什么办法可以实现吗?

编辑:好的,在查看了 cmets 中的相关条目之后,这是发生了什么。

有 3 件事需要改变:

  1. A 类应该有一个虚函数,以便它被认为是多态的
  2. 需要导出派生类。 BOOST_CLASS_EXPORT(B)
  3. oa

它与标准的 binary_oarchive 以及 polymorphic_binary_oarchive 一起使用。

EDIT2:当我说 b.cpp(.h) 和 main.cpp 时,BOOST_CLASS_EXPORT 会导致重复符号:

重复符号 boost::archive::detail::extra_detail::init_guid::g

【问题讨论】:

  • 序列化函数不应该是virtual吗?
  • 查看我的编辑,仍然无法使用多态存档器和 boost_class_export
  • @fefe:没有虚拟模板函数这样的东西。

标签: c++ serialization boost


【解决方案1】:

我必须承认我不熟悉这个boost 包,但是我复制并编译了代码,它产生了与OP 提到的相同的结果

意识到我们正在使用多态性,我在class A 中添加了一个public: virtual ~A(){};。另外,根据文档在main中添加oa.register_type&lt;B&gt;();,输出变为:

A!
B!

根据规范,只有当declares or inherits a virtual function 时,一个类才是polymorphic class。对于非多态的分类,也许多态是行不通的。

编辑:

BOOST_CLASS_EXPORT(B); 放入B.cpp 而不是B.h 似乎可以解决这个重新定义的问题。

编辑:

查看BOOST_CLASS_EXPORT(B)的展开结果(重新格式化):

namespace boost {
    namespace serialization {
        template<> struct guid_defined<B> : boost::mpl::true_ {};
        template<> inline const char * guid<B>(){ return "B"; }
    }
}
namespace boost {
    namespace archive {
        namespace detail {
            namespace { // NOTE
                template<> struct init_guid< B > {
                    static guid_initializer< B > const & g;
                };
                guid_initializer< B > const & init_guid< B >::g = ::boost::serialization::singleton< guid_initializer< B > >::get_mutable_instance().export_guid();
            }
        }
    }
}

并且对于标有NOTE的行:对于boost 1.42使用了一个匿名命名空间,如果将它放入多个cpp文件或放入一个头文件中都没有问题(在ubuntu中使用g ++测试,使用boost 包随 Ubuntu 一起提供)。但是在boost 1.48中,使用了namespace extra_detail,当放入多个cpp文件时会出现问题(在VS2010的windows中测试,使用从主页下载的boost)。

【讨论】:

猜你喜欢
  • 2018-12-13
  • 2015-01-13
  • 1970-01-01
  • 2015-03-04
  • 2012-02-05
  • 2012-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多