通过指向派生类的基本指针增强序列化 [英] Boost Serialization via base pointer to derived class

查看:65
本文介绍了通过指向派生类的基本指针增强序列化的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

可能重复:
使用多态档案进行加速序列化

我试图使用指向派生类的基指针来序列化我的类,但这仅序列化基类.

我刚刚阅读了 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!

很显然,我要查找的输出是A! B !.有什么办法可以实现?

编辑:好,在查看注释中的相关条目之后,这就是发生的情况.

有3件事需要更改:

  1. A类应该具有虚函数,以便被认为是多态的
  2. 需要导出派生类. BOOST_CLASS_EXPORT(B)
  3. oa<< b而不是oa<< * b

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

EDIT2 :当我说b.cpp(.h)和main.cpp时,BOOST_CLASS_EXPORT产生重复的符号:

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

解决方案

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

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

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文件或头文件中(使用g ++在ubuntu中进行测试,使用boost软件包随Ubuntu一起提供).但是,在boost 1.48中,使用了namespace extra_detail,当将其放入多个cpp文件时(使用从首页下载的boost在VS2010中在Windows中进行测试)会导致问题.

Possible Duplicate:
Boost Serialization using polymorphic archives

I am trying to serialize my classes using a base pointer to a derived class, but that only serializes the base class.

I just read http://www.boost.org/doc/libs/1_32_0/libs/serialization/doc/special.html#registration, but both the export macro and the register function didn't seem to change anything.

Consider the following, very basic, class hierarchy:

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

Output will be:

A!

Clearly, the output I'm looking for is A! B!. Is there any way this can be achieved ?

EDIT: Ok, after looking at the related entry in the comments, here is what is going on.

There was 3 things to change:

  1. class A should have a virtual function so that it is considered polymorphic
  2. need to export derived classes. BOOST_CLASS_EXPORT(B)
  3. oa << b instead of oa << *b

It works with a standard binary_oarchive, as well as the polymorphic_binary_oarchive.

EDIT2: When I have let's say b.cpp(.h) and main.cpp, the BOOST_CLASS_EXPORT results in duplicate symbols:

duplicate symbol boost::archive::detail::extra_detail::init_guid::g

解决方案

I must admit I am not familiar with this boost package, but I copied and compiled the code, which produced the same result as the OP mentioned

Realizing that we are using polymorphism, I added a public: virtual ~A(){}; in class A. Also, oa.register_type<B>(); is added in main according to the document, and output became:

A!
B!

According to the specification, a class is a polymorphic class only when declares or inherits a virtual function. For non-polymorphic classed, maybe polymorphism just does not work.

EDIT:

Putting the BOOST_CLASS_EXPORT(B); in B.cpp instead of B.h seems to solve this problem of redefinition.

EDIT:

Checked the expansion result of BOOST_CLASS_EXPORT(B) (reformatted):

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();
            }
        }
    }
}

And for the line marked with NOTE: for boost 1.42 used an anonymous namespace is used, which will be no problem if it is put into multiple cpp files or put into a header file (tested in ubuntu with g++, using the boost package come along with Ubuntu). However, in boost 1.48, namespace extra_detail is used, which would cause problems when put into multiple cpp files (tested in windows with VS2010, using boost downloaded from homepage).

这篇关于通过指向派生类的基本指针增强序列化的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆