使用Boost

时间:2016-02-02 13:22:58

标签: c++ serialization boost

当我使用boost序列化派生类并尝试仅反序列化基本部分时,我得到输入流错误。我猜我的代码错了。有没有办法使用boost存档仅反序列化派生对象的基本部分? 这段代码的原因是我试图实现一个设计来将派生对象从一个进程发送到另一个进程。接收过程将查看基本部分中的ID以确定接收哪个派生对象。

这是测试代码,我试图使用boost来验证这是可能的,但是在执行此操作时出现输入流错误

class DataIface
{
 public:
DataIface()
:num(0)
{
}
DataIface( int num):
    num(num)
{
}
int num;
template< class Archive >
    void serialize( Archive& ar, const unsigned int version )
    {
        std::cout<<"Serializing base class \n"<<std::endl;
        ar & num;
    }
};

class Data1 : public DataIface
{
private:
friend class boost::serialization::access;
public:
Data1()
:a(0)
{

};
Data1( int a, int num):
    DataIface(num),
    a(a)
{

}
int a;
template< class Archive >
void serialize( Archive& ar, const unsigned int version )
{
    std::cout<<"Serializing derived class \n"<<std::endl;
    ar & boost::serialization::base_object<DataIface>(*this);
    ar & a;

}

};

int main()
{
Data1 obj(10, 20);
std::ostringstream oss;
boost::archive::text_oarchive oa( oss );

oa << obj;

Data1 obj2;

std::istringstream iss(oss.str());
boost::archive::text_iarchive ia( iss );

ia >> obj2;

cout<< obj2.a << std::endl;
cout << obj2.num << std::endl;

DataIface iface;
try
{
 ia >> iface;
}
catch(std::exception& e)
{
    std::cout<<e.what()<<std::endl;
}
cout << iface.num << std::endl;



return 0;
}

任何帮助将不胜感激

1 个答案:

答案 0 :(得分:0)

  

这是测试代码,我试图验证这是可能的使用提升,我得到输入流错误

结论是什么?

结论是:它不起作用。这是因为它不是一个功能。没有文档中的哪个地方甚至建议你可以这样做。

运行时多态性

只是按预期使用多态!

<强> Live On Coliru

#include <iostream>
#include <sstream>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/export.hpp>

class DataIface {
  public:
    virtual ~DataIface() {}
    template <class Archive> void serialize(Archive &ar, const unsigned int version) {
        std::cout << __PRETTY_FUNCTION__ << "\n";
    }
};

class Data1 : public DataIface {
    friend class boost::serialization::access;

  public:
    Data1(int a=0) : a(a) {}
    int a;
    template <class Archive> void serialize(Archive &ar, const unsigned int version) {
        std::cout << __PRETTY_FUNCTION__ << "\n";
        ar &boost::serialization::base_object<DataIface>(*this);
        ar &a;
    }
};

class Data2 : public DataIface {
    friend class boost::serialization::access;

  public:
    Data2(int b=0) : b(b) {}
    int b;
    template <class Archive> void serialize(Archive &ar, const unsigned int version) {
        std::cout << __PRETTY_FUNCTION__ << "\n";
        ar &boost::serialization::base_object<DataIface>(*this);
        ar &b;
    }
};


BOOST_CLASS_EXPORT(Data1)
BOOST_CLASS_EXPORT(Data2)

int main() {

    DataIface* tests[] = { new Data1(10), new Data2(-10) };

    for(auto testobj : tests)
    {
        std::ostringstream oss;
        {
            boost::archive::text_oarchive oa(oss);

            oa << testobj;
        }

        {
            std::istringstream iss(oss.str());
            boost::archive::text_iarchive ia(iss);

            DataIface* obj = nullptr;
            ia >> obj;

            if (Data1* obj1 = dynamic_cast<Data1*>(obj))
                std::cout << "It's a Data1: " << obj1->a << "\n";
            if (Data2* obj2 = dynamic_cast<Data2*>(obj))
                std::cout << "It's a Data2: " << obj2->b << "\n";
        }
    }

    for(auto ptr : tests) delete ptr;
}

打印:

void Data1::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive]
void DataIface::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive]
void Data1::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_iarchive]
void DataIface::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_iarchive]
It's a Data1: 10
void Data2::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive]
void DataIface::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_oarchive]
void Data2::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_iarchive]
void DataIface::serialize(Archive&, unsigned int) [with Archive = boost::archive::text_iarchive]
It's a Data2: -10

静态多态性

或者,使用变体。这样可以省去手动动态分配的麻烦和虚拟调度的潜在成本。

<强> Live On Coliru

#include <iostream>
#include <sstream>

#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/serialization.hpp>
#include <boost/serialization/variant.hpp>

class Data1 {
    friend class boost::serialization::access;

  public:
    Data1(int a=0) : a(a) {}
    int a;
    template <class Archive> void serialize(Archive &ar, const unsigned int version) {
        ar &a;
    }

    friend std::ostream& operator<<(std::ostream& os, Data1 const& d) {
        return os << "It's a Data1: " << d.a;
    }
};

class Data2 {
    friend class boost::serialization::access;

  public:
    Data2(int b=0) : b(b) {}
    int b;
    template <class Archive> void serialize(Archive &ar, const unsigned int version) {
        ar &b;
    }

    friend std::ostream& operator<<(std::ostream& os, Data2 const& d) {
        return os << "It's a Data2: " << d.b;
    }
};

int main() {

    using V = boost::variant<Data1, Data2>;
    V tests[] = { Data1{10}, Data2{-10} };

    for(auto testobj : tests)
    {
        std::ostringstream oss;
        {
            boost::archive::text_oarchive oa(oss);
            oa << testobj;
        }

        {
            std::istringstream iss(oss.str());
            boost::archive::text_iarchive ia(iss);

            V deserialized;
            ia >> deserialized;

            std::cout << deserialized << "\n";
        }
    }
}

打印:

It's a Data1: 10
It's a Data2: -10