2009-01-26 15 views
9

मैं क्लाइंट-सर्वर एप्लिकेशन पर काम कर रहा हूं जो इसकी क्रमबद्धता आवश्यकताओं के लिए boost :: serialization लाइब्रेरी का उपयोग करता है।पॉलिमॉर्फिक अभिलेखागार का उपयोग करके बूस्ट सीरियलाइजेशन

मुझे पॉलिमॉर्फिक ऑब्जेक्ट्स को क्रमबद्ध और deserialize करने की आवश्यकता है जो काम नहीं कर रहा है। दस्तावेज़ीकरण कहता है कि यह समर्थित है लेकिन संबंधित उदाहरणों में से कोई भी यह दर्शाता है कि मैं यहां क्या करने की कोशिश कर रहा हूं। तो, मुझे पूरा यकीन नहीं है। मेरा सवाल है बूस्ट का उपयोग कर polymorphic वस्तुओं serialize/deserialize कर सकते हैं? यदि हाँ, मैं यहाँ क्या गलत कर रहा हूँ?

धन्यवाद!

कोड:

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

कृपया अपना कोड दोबारा सुधारें। कोड के एक बड़े ब्लॉक के रूप में इसे दिखाने के लिए आपको इसे सभी को इंडेंट करना होगा। –

+0

भले ही इसकी पृष्ठभूमि आपके नेटवर्किंग ऐप है, फिर भी प्रश्न या विषय में नेटवर्किंग के साथ कुछ लेना देना नहीं है। शायद "नेटवर्क प्रोग्रामिंग" टैग अप्रचलित है? – sharkin

उत्तर

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

आप अभी पॉलिमॉर्फिक संग्रह से पारंपरिक टेम्पलेट संग्रह में बदल गए हैं। यह काम करता है, लेकिन चेतावनी के साथ। डंपबिन/निर्यात आप पर निर्भर करता है कि यह आपको विंडोज पर कितना ब्लोट देता है। यह वास्तव में आश्चर्यजनक है। – kizzx2

3

बस कुछ टिप्पणियां ...

सबसे पहले, आप को क्रमानुसार और एक टेम्प्लेटेड संस्करण का उपयोग कर deserialize करने के लिए एक ही आपरेशन का उपयोग कर सकते हैं: मैक्रो के बजाय

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

इसके अलावा, आप उन प्रकारों को पॉइंटर्स के रूप में पहचाने जाने के लिए संग्रह को "कॉन्फ़िगर" कर सकते हैं:

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

register_type मेरे लिए भी इस समस्या को हल करता है, लेकिन मेरे जीवन के लिए मैं यह नहीं समझ सकता कि मेरी कक्षा संरचना के कुछ हिस्सों में register_type की मांग क्यों होती है, और अन्य नहीं –

संबंधित मुद्दे