2012-01-11 174 views
1

我有一个奇怪的问题,试图将指针反序列化与升压序列化派生类。我有一个基地,每个我尝试反序列化的指针我得到任何“输入流错误”异常或“未注册类”异常时他们外面SAVE/LOAD功能(非侵入式版本),但得到的。这是我做的:问题使用Boost反序列化指针的派生类:序列化

首先我定义我的班:

#include <fstream> 
#include <iomanip> 

#include <boost/archive/xml_iarchive.hpp> 
#include <boost/archive/xml_oarchive.hpp> 
#include <boost/archive/archive_exception.hpp> 
#include "boost/serialization/split_free.hpp" 
#include "boost/serialization/export.hpp" 
#include "boost/serialization/utility.hpp" 
#include <boost/serialization/string.hpp> 
#include <boost/serialization/binary_object.hpp> 

class Base 
{ 
public: 
    bool isEnabled; 
    Base(); 
    virtual ~Base(){} 
}; 
Base::Base() 
{ 
    isEnabled = 0; 
} 

class Derived : public Base 
{ 

public: 
    Derived(); 
    virtual ~Derived(){} 
    int layerHeight; 
}; 
Derived::Derived():Base() 
{} 

然后我要确保他们的特点是什么,我需要:

BOOST_CLASS_EXPORT_GUID(Base, "Base") 
BOOST_SERIALIZATION_SPLIT_FREE(Base) 
BOOST_CLASS_IS_WRAPPER(Base) 
BOOST_CLASS_TRACKING(Base, boost::serialization::track_selectively) 
BOOST_CLASS_IMPLEMENTATION(Base, boost::serialization::object_class_info) 

BOOST_SERIALIZATION_SPLIT_FREE(Derived) 
BOOST_CLASS_EXPORT_GUID(Derived, "Derived") 
BOOST_CLASS_IS_WRAPPER(Derived) 
BOOST_CLASS_IMPLEMENTATION(Derived, boost::serialization::object_class_info) 
BOOST_CLASS_TRACKING(Derived, boost::serialization::track_selectively) 

接下来我定义实际保存/加载功能:

namespace boost { 

    namespace serialization { 

    template<class Archive> 
    void save(Archive & ar,const Base& obj, const unsigned int version) 
    { 
     bool isEnabled = obj.isEnabled; 
     ar << BOOST_SERIALIZATION_NVP(isEnabled); 
    } 
    template<class Archive> 
    void load(Archive & ar, Base& obj, const unsigned int version) 
    { 
     bool isEnabled; 
     ar >> BOOST_SERIALIZATION_NVP(isEnabled); 
    } 
    } // namespace serialization 
} // namespace boost 

namespace boost { 
template<> 
struct is_virtual_base_of<Base, Derived>: public mpl::true_ {}; 

namespace serialization { 

template<class Archive> 
void save(Archive & ar,const Derived& obj, const unsigned int version) 
{ 
    ar & boost::serialization::base_object<Base>(obj); 
    int height =obj.layerHeight; 
    ar << BOOST_SERIALIZATION_NVP(height); 
} 
template<class Archive> 
void load(Archive & ar, Derived& obj, const unsigned int version) 
{ 
    ar.template register_type<Base>(); 
    ar.template register_type<Derived>(); 
    ar & boost::serialization::base_object<Base>(obj); 
    int height; 
    ar >> BOOST_SERIALIZATION_NVP(height); 
} 
} // namespace serialization 
} // namespace boost 

而且2 SAVE/LOAD佣工我从文档

template <typename T> 
void save_schedule(const T& s, const char * filename){ 
    // make an archive 
    std::ofstream ofs(filename); 
    assert(ofs.good()); 
    boost::archive::xml_oarchive oa(ofs); 
    oa << BOOST_SERIALIZATION_NVP(s); 
} 

template <typename T> 
void restore_schedule(T &s, const char * filename) 
{ 
    // open the archive 
    std::ifstream ifs(filename); 
    assert(ifs.good()); 
    boost::archive::xml_iarchive ia(ifs); 
    // restore the schedule from the archive 
    ia >> BOOST_SERIALIZATION_NVP(s); 
} 

最后 - 这里是我尝试使用它所有

int main(int argc, char *argv[]) 
{ 
    Base* basePointer = new Base(); 
    Base* objectPointer = new Derived(); 
    Derived * secondObjectPointer = new Derived(); 
    Derived justObject; 

    save_schedule(basePointer, "C:\\basePointer.xml"); 
    save_schedule(objectPointer, "C:\\objectPointer.xml"); 
    save_schedule(secondObjectPointer , "C:\\secondObjectPointer.xml"); 
    save_schedule(justObject, "C:\\justObject.xml"); 

    //this works OK 
    restore_schedule(basePointer, "C:\\basePointer.xml"); 

    //this gives "Input Stream Error" 
    restore_schedule(objectPointer, "C:\\objectPointer.xml"); 

    //this gives "Unregistered class" 
    restore_schedule(secondObjectPointer, "C:\\secondObjectPointer.xml"); 

    //This works >__< But I need to serialize pointers so I cannot use this 
    restore_schedule(justObject, "C:\\justObject.xml"); 
} 

我在做什么错?为什么我不能反序列化除了指向基类的指针之外的其他任何东西?

+0

如果你解决你的问题,发布溶液作为_answer_。 – 2012-01-11 15:49:01

+0

对于这一点,我需要找到如何做到这一点:)对不起,我是全新的。附:似乎我将无法将它作为下一个4小时的答案发布 - 网站限制 – Zeks 2012-01-11 16:14:12

+0

那么它毕竟不是解决方案?你说问题解决了。 – 2012-01-11 16:16:28

回答

6

UPD ::经过一番搜索,我能够追踪我的问题,以这样的回答:

boost serialization exception: unregistered class, serializing polymorphic base problem

更换

//original taken from Boost Docs 
ar & boost::serialization::base_object<Base>(obj); 

// taken from the link above (macro expanded) 
ar & boost::serialization::make_nvp(BOOST_PP_STRINGIZE(obj),boost::serialization::base_object<Base >(obj)); 

做解决问题。

作为一个附注 - 我发现了另一种类型的奇怪的错误,可能会出现并导致“流输入错误”。它的工作原理是这样的:

如果连一个构造函数在您的层次结构,可以初始化变量(任何变量),但不 - 你会得到流输入错误尝试反序列化。

如果在一个类中没有的变量 - 一切正常。但是如果甚至有一个 - 你必须在该类的构造函数中初始化至少一个变量!我不知道为什么这很重要,但这解决了我的一个主要问题。

+0

其实,我非常想听到一个解释,当我没有在基类的构造函数中初始化任何东西时会发生什么。我的意思是 - 我仍然明确地用它来调用它:Base()...它是否被优化或者什么都没有被执行, – Zeks 2012-01-12 07:30:24

+3

Boost强大,但是..呃。我花了最后2个小时试图序列化派生类。阅读教程/书没有好处。你的帖子解决了我的编译错误。仍然不知道**为什么即使官方教程没有设法显示这个库的正确使用** – emesx 2012-09-04 20:39:47

+2

其实,这个问题(提高没有有用的检查/忘记提及重要的事情)是一个反复出现的问题。每当我尝试使用boost> _ Zeks 2012-09-04 22:33:58