【问题标题】:How to serialize a self-defined class containing a STL container of another self-defined class using boost serialization easily?如何使用boost序列化轻松序列化包含另一个自定义类的STL容器的自定义类?
【发布时间】:2015-12-09 09:57:21
【问题描述】:

我已经阅读了这里的教程http://www.boost.org/doc/libs/1_59_0/libs/serialization/doc/index.html 并搜索了很多页面,但我仍然不知道该怎么做。

我已经阅读了如何序列化自定义类以及如何序列化包含 std::string 或指针的 STL 容器的自定义类。但是我不确定如何使用boost序列化轻松序列化包含另一个自定义类的STL容器的自定义类?由于 std::string 和指针是标准的 C++ 类型,boost 知道如何处理它们。如果是自定义类的 STL 容器,我觉得我必须告诉 boost 在序列化时如何处理它。但是怎么做?这是我自定义的2个类。

class Instance
{
public:
    Instance(){}
    ~Instance();
    //... a lot of functions here.
private:
    InstanceIdentity identity_;
    mutable ClassLabel class_label_;
    mutable FeatureGroup features_;
    friend class InstanceManager;
};

class InstanceManager
{
public:
    InstanceManager(){}
    ~InstanceManager();
    // a lot of functions here.
private:
    set<Instance> instances_;
};

根据http://www.boost.org/doc/libs/1_59_0/libs/serialization/doc/index.html的教程部分,由于boost知道如何处理STL容器,所以我需要做的是添加

friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
    ar & instances_;
}

在类 InstanceManager 中。并添加

friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
    // A lot of things like the following example.
    //ar & degrees;
    //ar & minutes;
    //ar & seconds;
}

在类实例中。那正确吗?或者有更好的方法。通过编码来测试这一点需要很多时间。那么,谁能告诉我答案?

【问题讨论】:

    标签: c++ serialization boost stl


    【解决方案1】:

    答案是肯定的。这是一个完整的工作示例。我发明了一些简单的类型:

    struct InstanceIdentity { int id;            };
    struct ClassLabel       { std::string value; };
    struct FeatureGroup     { size_t count;      };
    

    使用非侵入式序列化:

    namespace boost { namespace serialization {
        template <typename Ar>
            void serialize(Ar& ar, InstanceIdentity& ii, unsigned) { ar & ii.id; }
        template <typename Ar>
            void serialize(Ar& ar, ClassLabel& cl, unsigned) { ar & cl.value; }
        template <typename Ar>
            void serialize(Ar& ar, FeatureGroup& fg, unsigned) { ar & fg.count; }
    } }
    

    InstanceInstanceManager 类将它们的序列化方法作为成员(由于私有成员):

    template <typename Ar>
        void Instance::serialize(Ar& ar, unsigned) { ar & identity_ & class_label_ & features_; }
    
    template <typename Ar>
        void InstanceManager::serialize(Ar& ar, unsigned) { ar & instances_; }
    

    Live On Coliru

    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/serialization/set.hpp>
    #include <boost/serialization/serialization.hpp>
    #include <boost/serialization/access.hpp>
    
    struct InstanceIdentity { int id;            };
    struct ClassLabel       { std::string value; };
    struct FeatureGroup     { size_t count;      };
    
    class Instance
    {
    public:
        Instance(){}
        ~Instance() = default;
        //... a lot of functions here.
    
        bool operator<(Instance const& other) const {
            return identity_.id < other.identity_.id;
        }
    private:
        InstanceIdentity identity_;
        mutable ClassLabel class_label_;
        mutable FeatureGroup features_;
        friend class InstanceManager;
    
        friend class boost::serialization::access;
        template <typename Ar>
            void serialize(Ar& ar, unsigned) { ar & identity_ & class_label_ & features_; }
    };
    
    class InstanceManager
    {
    public:
        InstanceManager()
        {
            Instance a, b, c;
    
            a.class_label_.value = "label a";
            b.class_label_.value = "label b";
            c.class_label_.value = "label c";
    
            a.features_.count = 42;
            b.features_.count = 24;
            c.features_.count = -9;
    
            a.identity_.id = rand();
            b.identity_.id = rand();
            c.identity_.id = rand();
    
            instances_.insert(instances_.end(), a);
            instances_.insert(instances_.end(), b);
            instances_.insert(instances_.end(), c);
        }
    
        ~InstanceManager() = default;
        // a lot of functions here.
    private:
        std::set<Instance> instances_;
    
        friend class boost::serialization::access;
        template <typename Ar>
            void serialize(Ar& ar, unsigned) { ar & instances_; }
    };
    
    namespace boost { namespace serialization {
        template <typename Ar>
            void serialize(Ar& ar, InstanceIdentity& ii, unsigned) { ar & ii.id; }
        template <typename Ar>
            void serialize(Ar& ar, ClassLabel& cl, unsigned) { ar & cl.value; }
        template <typename Ar>
            void serialize(Ar& ar, FeatureGroup& fg, unsigned) { ar & fg.count; }
    } }
    
    int main() {
    
        InstanceManager im;
    
        boost::archive::text_oarchive oa(std::cout);
        oa << im;
    
    }
    

    打印

    22 serialization::archive 12 0 0 0 0 3 0 0 0 0 0 846930886 0 0 7 label b 0 0 24 1681692777 7 label c 18446744073709551607 1804289383 7 label a 42

    【讨论】:

    • 非常感谢。我已经使用文本文件解决了 boost 序列化。现在我正在尝试将实例序列化为二进制文件,但遇到了新问题。我在这里发布了一个新问题 stackoverflow.com/questions/32804174/… 。如果您能提供一些帮助,我将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多