簡體   English   中英

如何使用boost使用shared_ptr成員序列化對象

[英]How to serialize object with shared_ptr member using boost

有抽象的I1和派生的C1

有抽象的I2和派生的C2

I1shared_ptr<I2> 如何使用boost serializaton使它們可序列化? 我正在做它,但我的應用程序得到例外。

#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>

struct I1
{
    I1() {}
    virtual ~I1() = 0 {}

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

struct C1 : I1
{
    virtual ~C1() {}

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<I1>(*this);
    }
};

struct I2
{
    virtual ~I2() = 0 {}

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & p;
    }

    boost::shared_ptr<I1> p;
};

struct C2 : I2
{
    C2() { p = boost::shared_ptr<I1>(new C1); }
    virtual ~C2() { }

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<I2>(*this);
    }
};

int main()
{
    C2 c2;

    std::string s;
    std::stringstream ss(s);

    boost::archive::binary_oarchive oa(ss);
    oa.register_type<I1>();
    oa.register_type<C1>();
    oa.register_type<I2>();
    oa.register_type<C2>();

    oa << c2;

    boost::archive::binary_iarchive ia(ss);
    //ia.register_type<I1>(); // cannot instantiate abstract class
    ia.register_type<C1>();
    //ia.register_type<I2>(); // cannot instantiate abstract class
    ia.register_type<C2>();

    ia >> c2;
}

boost序列化文檔在這里BOOST_CLASS_EXPORT有趣的事情:

...... BOOST_CLASS_EXPORT ......

因此,通過使用通過指針或對其基類的引用來操縱的派生類來暗示對導出的需要。

你的p指針就是這樣。 將這些宏添加到您的代碼中也可以擺脫來自main的丑陋的顯式register_type()調用,這也很好:)

所以,這段代碼似乎在VS2014中編譯和工作:

#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/archive/binary_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/export.hpp>

struct I1
{
    I1() {}
    virtual ~I1() = 0 {}

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

BOOST_CLASS_EXPORT(I1)

struct C1 : I1
{
    virtual ~C1() {}

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<I1>(*this);
    }
};

BOOST_CLASS_EXPORT(C1)

struct I2
{
    virtual ~I2() = 0 {}

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & p;
    }

    boost::shared_ptr<I1> p;
};

BOOST_CLASS_EXPORT(I2)

struct C2 : I2
{
    C2() { p = boost::shared_ptr<I1>(new C1); }
    virtual ~C2() { }

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<I2>(*this);
    }
};

BOOST_CLASS_EXPORT(C2)

int main()
{
    C2 c2;

    std::string s;
    std::stringstream ss(s);

    boost::archive::binary_oarchive oa(ss);
    oa << c2;

    boost::archive::binary_iarchive ia(ss);
    ia >> c2;
}

但有趣的是,Boost文檔的聲明顯然不適用於所有編譯器,並且互聯網上的大量代碼示例在VS2014中不起作用。

BOOST_SERIALIZATION_ASSUME_ABSTRACT(I1)
BOOST_SERIALIZATION_ASSUME_ABSTRACT(I2)

根據文檔http://www.boost.org/doc/libs/1_39_0/libs/serialization/doc/traits.html#abstract

UPDATE

我剛剛用VS2013RTM和Boost 1_55驗證了它,JustWorks(TM),我已經

  • 刪除了抽象基礎的類型注冊(它們永遠不能從存檔中具體加載)
  • 添加

     #pragma warning(disable: 4244) #include <boost/config/warning_disable.hpp> 

    在文件的頂部,沉默已知的健談警告

代碼編譯並運行無誤。 對於好的風格,你應該

這是我最終得到的完整代碼:

#pragma warning(disable: 4244)
#include <boost/config/warning_disable.hpp>
#include <sstream>
#include <boost/shared_ptr.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/shared_ptr.hpp>

struct I1
{
    I1() {}
    virtual ~I1() = 0 {}

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

struct C1 : I1
{
    virtual ~C1() {}

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<I1>(*this);
    }
};

struct I2
{
    virtual ~I2() = 0 {}

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & p;
    }

    boost::shared_ptr<I1> p;
};

struct C2 : I2
{
    C2() { p = boost::shared_ptr<I1>(new C1); }
    virtual ~C2() { }

    template<class Archive>
    void serialize(Archive &ar, const unsigned int version)
    {
        ar & boost::serialization::base_object<I2>(*this);
    }
};

int main()
{
    boost::shared_ptr<I2> c2(new C2);

    std::string s;
    std::stringstream ss(s);

    boost::archive::text_oarchive oa(ss);
    oa.register_type<C1>();
    oa.register_type<C2>();

    oa << c2;
    std::cout << "Serialized form: '" << ss.str() << "'\n";

    boost::archive::text_iarchive ia(ss);
    ia.register_type<C1>();
    ia.register_type<C2>();

    ia >> c2;
}

這是輸出:

在此輸入圖像描述

我認為您不應該在輸出存檔上注冊您的純虛擬類。

或者,您可以使用導出 定義類后,用以下代碼替換其余代碼:

#include <boost/serialization/export.hpp>
BOOST_CLASS_EXPORT(C1)
BOOST_CLASS_EXPORT(C2)

int main()
{
    C2 c2;

    std::string s;
    std::stringstream ss(s);

    {
       boost::archive::binary_oarchive oa(ss);
       oa << c2;
    }

    boost::archive::binary_iarchive ia(ss);
    ia >> c2;
}

我將輸出存檔放入一個單獨的塊中。 我認為它很可能沒有它,但我想確保一切都被刷新(通過超出范圍)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM