2012-03-15 67 views
6

我已经阅读了大量类似的问题,但没有找到答案。我正在使用Visual Studio 2010并提升1.47。派生对象的boost序列化不调用派生的序列化()

下面的代码,它是完整的,可编译:

#include "stdafx.h" 

#include <string> 
#include <sstream> 

#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 

#include <boost/serialization/export.hpp> 

using namespace std; 

class BaseObject 
{ 
public: 

    BaseObject(void) { }; 
    virtual ~BaseObject(void) { }; 

    template<class Archive> 
     void serialize(Archive &ar, const unsigned int version) 
     { /* nothing happens here */ }; 
}; 

class DerivedObject : public BaseObject 
{ 
public: 

    string text; 

public: 

    DerivedObject(void) { }; 
    ~DerivedObject(void) { }; 

    template<class Archive> 
     void serialize(Archive &ar, const unsigned int version) 
     { 
      ar & text; 
     }; 
}; 

BOOST_CLASS_EXPORT(DerivedObject) 

int _tmain(int argc, _TCHAR* argv[]) 
{ 
    DerivedObject der; 
    der.text = "Testing!"; 

    std::ostringstream os; 
    boost::archive::text_oarchive oa(os); 
    oa.register_type<DerivedObject>(); 

    // I made a DerivedObject, but I'm casting it to a BaseObject 
    // as the serialization code should not have to know what type it is 
    BaseObject *base = &der; 
    // now serialize it 
    oa << *base; 

    printf("serialized: %s\r\n",os.str().c_str()); 

    return (0); 
} 

你可以看到它的真正简单,我添加了是应该确保DerivdObject ::序列化BOOST_CLASS_EXPORT和oa.register_type魔术()被称为即使它不是一个虚拟的方法..但仍然只调用BaseObject中的serialize()。一个特定于Visual C++的问题?请指教?

+1

不应该将'BaseObject :: serialize'标记为'virtual'? – Nick 2012-03-15 10:45:25

+0

不,它是一个模板,它不可能 – 2012-03-15 10:50:41

+0

好点 - 没有注意到模板位! – Nick 2012-03-15 10:53:46

回答

2

正如描述的boost serialization documentation你需要告诉你的派生类中调用基类的序列码。只需编写你的派生类序列化方法,如下所示:

template<class Archive> 
    void serialize(Archive &ar, const unsigned int version) 
    { 
     ar & boost::serialization::base_object<BaseObject>(*this); 
     ar & text; 
    }; 
0

我还没有在调试器或任何东西中试过这个,但它看起来可能是切片的情况。也许你可以找到通过修改代码以指针或引用,而不是通过值序列化,像这样......

BaseObject *base = &der; 
oa << base; // Serialize a pointer 

......或者......

BaseObject& base = der; 
oa << base; // Serialize a reference 
+0

谢谢,但第一个引发异常,未注册类的东西,另一个与我的代码基本相同。同样的结果... – CodeOrElse 2012-03-16 12:04:21

+0

我后来意识到'''操作符可能通过引用引用参数,这使我的理论完全错误。抱歉。你有没有试过注册基类?我正在使用这个东西在工作中的当前项目,但所有的细节都由其他人设置,所以我不完全清楚在设置部分。 :/ – aldo 2012-03-16 16:15:31

+0

我刚刚尝试注册基类,它没有工作,对不起。 – CodeOrElse 2012-03-16 21:12:06

0

这不是绝对是一个答案,只是一个可行的解决方法。

在基础类添加:

virtual void StreamToArchive(boost::archive::text_oarchive &oa) = 0; 

然后定义一个宏STREAMTOARCHIVE并把它的每一个派生类中的一个。

#define STREAMTOARCHIVE void StreamToArchive(boost::archive::text_oarchive &oa) { oa << *this; } 

然后在主,更换

oa << base; 

base.StreamToArchive(oa); 

是啊,我知道,这是丑陋的,但..还有它的作品,我只是把那个STREAMTOARCHIVE宏派生类...我可以忍受那个...

但是然后...解析它回到一个对象,现在这是一个诺特尔重要...

编辑:改变“这个”到“*这个”