2009-01-26 24 views
9

Tôi đang làm việc trên một ứng dụng máy khách-máy chủ sử dụng tăng :: thư viện tuần tự hóa cho các nhu cầu tuần tự hóa của nó.Tăng tuần tự hóa bằng cách sử dụng các lưu trữ đa hình

Tôi cần phải tuần tự hóa và deserialize các đối tượng đa hình dường như không hoạt động. Tài liệu này nói rằng nó được hỗ trợ nhưng không có ví dụ nào liên quan chứng minh những gì tôi đang cố gắng làm ở đây. Vì vậy, tôi không chắc lắm. Câu hỏi của tôi là có thể serialize/deserialize đối tượng đa hình bằng cách sử dụng tăng? Nếu có, tôi đang làm gì sai ở đây?

Cảm ơn!

mã:

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

Vui lòng định dạng lại mã của bạn. Bạn cần thụt lề tất cả để làm cho nó hiển thị như một khối mã lớn. –

+0

Mặc dù nền tảng của ứng dụng mạng này, câu hỏi hoặc chủ đề trong chính nó không liên quan gì đến mạng. Có lẽ thẻ "lập trình mạng" đã lỗi thời? – sharkin

Trả lời

10

Tìm thấy một nghị quyết. Tôi đã phải xuất lớp dẫn xuất với tuyên bố:

BOOST_CLASS_EXPORT(derived); 

Đăng nội dung nào đó hoạt động với một số sửa chữa.

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

Bạn vừa thay đổi từ kho lưu trữ đa hình sang kho lưu trữ mẫu truyền thống. Nó hoạt động, nhưng với sự cẩn thận. Dumpbin/xuất khẩu trên bạn exe để xem có bao nhiêu bloat nó mang lại cho bạn trên Windows. Nó thực sự tuyệt vời. – kizzx2

3

Chỉ cần một vài ý kiến ​​...

Trước tiên, bạn có thể sử dụng các hoạt động tương tự để serialize và deserialize sử dụng một phiên bản templated:

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

Ngoài ra, thay vì vĩ mô, bạn có thể "định cấu hình" tệp lưu trữ để mong đợi các loại được công nhận là con trỏ:

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

register_type giải quyết vấn đề này cho tôi là tốt, nhưng đối với cuộc sống của tôi tôi không thể tìm ra lý do tại sao một số phần của cấu trúc lớp của tôi yêu cầu register_type, và những người khác không –

Các vấn đề liên quan