2009-01-26 91 views
9

我正在使用boost :: serialization库来处理序列化需求的客户端服务器应用程序。使用多态存档提升序列化

我需要序列化和反序列化似乎不起作用的多态对象。该文档确实表示它受到支持,但没有任何相关示例能够证明我在这里要做的事情。所以,我不太确定。我的问题是可以使用boost来序列化/反序列化多态对象?如果是的话,我在这里做错了什么?

谢谢!

代码:

using namespace std; 

class base { 
    public: 
    int data1; 

    friend class boost::serialization::access; 

    void serialize(boost::archive::polymorphic_iarchive & ar, 
        const unsigned int file_version) { 
     ar & data1; 
    } 

    void serialize(boost::archive::polymorphic_oarchive & ar, 
        const unsigned int file_version){ 
     ar & data1; 
    } 

    public: 
    base() {}; 
    base(int _d) : data1(_d) {} 
    virtual void foo() const {std::cout << "base" << std::endl;} 
}; 

class derived : public base { 
    public: 
    int data2; 

    friend class boost::serialization::access; 

    void serialize(boost::archive::polymorphic_iarchive & ar, 
        const unsigned int file_version) { 
     ar & boost::serialization::base_object<base>(*this) & data2; 
    } 

    void serialize(boost::archive::polymorphic_oarchive & ar, 
        const unsigned int file_version){ 
     ar & boost::serialization::base_object<base>(*this) & data2; 
    } 

    public: 
    derived() {}; 
    derived(int _b, int _d) : base(_b), data2(_d) {} 
    virtual void foo() const {std::cout << "derived" << std::endl;} 
}; 

int main(int argc, char *argv[]) { 
    // client 
    const base *b1 = new derived(1, 2); 

    std::ostringstream oss; 
    boost::archive::polymorphic_text_oarchive oa(oss); 
    oa << *b1; 

    // server 
    base *b2 = new derived(3, 4); 

    std::istringstream iss(oss.str()); 
    boost::archive::polymorphic_text_iarchive ia(iss); 
    ia >> *b2; 

    // prints 1, ok 
    cout << b2->data1 << endl; 

    // prints 4, why wasn't the derived class data written? 
    cout << (dynamic_cast<derived*>(b2))->data2 << endl; 

    return 0; 
} 
+0

请重新格式化您的代码。您需要缩进所有内容才能使其显示为一大块代码。 – 2009-01-26 03:51:47

+0

即使这是你的网络应用程序的背景,这个问题或主题本身与网络无关。也许“网络编程”标签已过时? – sharkin 2009-01-26 08:27:50

回答

10

实测值的分辨率。我不得不导出派生类与声明:

BOOST_CLASS_EXPORT(derived); 

发布一些工作与一些更正。

using namespace std; 

class base { 
    public: 
    int data1; 

    friend class boost::serialization::access; 

    template<typename Archive> 
    void serialize(Archive & ar, const unsigned int file_version) { 
     ar & data1; 
    } 

    public: 
    base() {}; 
    base(int _d) : data1(_d) {} 
    virtual void foo() const {std::cout << "base" << std::endl;} 
}; 

class derived : public base { 
    public: 
    int data2; 

    friend class boost::serialization::access; 

    template<typename Archive> 
    void serialize(Archive & ar, const unsigned int file_version) { 
     ar & boost::serialization::base_object<base>(*this); 
     ar & data2; 
    } 

    public: 
    derived() {}; 
    derived(int _b, int _d) : base(_b), data2(_d) {} 
    virtual void foo() const {std::cout << "derived" << std::endl;} 
}; 

BOOST_CLASS_EXPORT(derived); 

int main(int argc, char *argv[]) { 
    // client 
    // Assign to base type 
    std::unique_ptr<const base> b1(new derived(1, 2)); 

    std::ostringstream oss; 
    boost::archive::text_oarchive oa(oss); 
    oa & b1.get(); 

    // server 
    // Retrieve derived type from base 
    std::unique_ptr<base> b2; 

    std::istringstream iss(oss.str()); 
    boost::archive::text_iarchive ia(iss); 
    { 
     base *temp; 
     ia & temp; 
     b2.reset(temp); 
    } 
    cout << b2->data1 << endl; 
    cout << (dynamic_cast<derived*>(b2.get()))->data2 << endl; 

    return 0; 
} 
+0

您刚刚从多态存档更改为传统模板存档。它有效,但有警告。你的exe文件中的Dumpbin/exports会显示它在Windows上的膨胀程度。它真的很棒。 – kizzx2 2010-10-11 13:27:52

3

短短几评论...

首先,你可以使用相同的操作序列化和使用模板版本反序列化:

template<class Archive> 
void load(Archive & ar, const unsigned int version) 
{ 
    ... 
} 

此外,而不是宏,可以“配置”存档以期望将这些类型识别为指针:

ar.register_type(static_cast<your_static_type_here *>(NULL));