2009-01-26 90 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));