Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
223 views
in Technique[技术] by (71.8m points)

c++ - Boost Serialization using polymorphic archives

I am working on a client-server application that uses boost::serialization library for it's serialization needs.

I need to serialize and deserialize polymorphic objects that does not seem to work. The documentation does say that it is supported but none of the related examples demonstrate what I'm trying to do here. So, I am not very sure. My question is can serialize/deserialize polymorphic objects using boost? If yes, what am I doing wrong here?

Thanks!

code:

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;  
}  
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Found a resolution. I had to export the derived class with the statement:

BOOST_CLASS_EXPORT(derived);

Posting something that works with some corrections.

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;  
}  

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...