【问题标题】:Boost Serialization using polymorphic archives使用多态档案促进序列化
【发布时间】:2023-03-04 16:48:01
【问题描述】:

我正在开发一个客户端-服务器应用程序,该应用程序使用 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;  
}  

【问题讨论】:

  • 请重新格式化您的代码。您需要缩进所有内容以使其显示为一大块代码。
  • 尽管这是您的网络应用程序的背景,但问题或主题本身与网络无关。也许“网络编程”标签已经过时了?

标签: c++ serialization boost


【解决方案1】:

找到解决方案。我必须使用以下语句导出派生类:

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

【讨论】:

  • 您刚刚从多态存档更改为传统的模板存档。它有效,但有一些警告。 Dumpbin /exports 在你的 exe 上查看它在 Windows 上给你带来了多少膨胀。真是太棒了。
【解决方案2】:

只有几厘米……

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

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

此外,除了宏,您可以“配置”存档以期望那些被识别为指针的类型:

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

【讨论】:

  • register_type 也为我解决了这个问题,但对于我的一生,我无法弄清楚为什么我的类结构的某些部分需要 register_type,而其他部分则不需要
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-27
  • 2012-04-05
  • 2018-06-05
  • 1970-01-01
  • 2013-02-03
相关资源
最近更新 更多