【问题标题】:boost serialization / Deserialization of std::vector<float> member failsstd::vector<float> 成员的 boost 序列化/反序列化失败
【发布时间】:2017-04-17 15:47:32
【问题描述】:

下午好,

我是第一次玩 boost::serialization,目前在一些非常基本的任务上失败了。我将我的代码简化为非常基本的,首先是一个只有一个 std::vector 成员的简单类的类定义:

#ifndef DATA_H
#define DATA_H

#include <string>
#include <vector>

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

namespace ml {
    class Data {
        private:
            std::vector<float> d;

            friend class boost::serialization::access;

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

            static Data Load(const std::string& filename);

            Data(const std::vector<float>& d);

            Data(const Data& rhs);
            Data();

            ~Data();

            Data& operator=(const Data& rhs);

            void save(const std::string& filename);

            std::vector<float> getD() const;
    };
}
#endif // DATA_H 

实现:

#include <iostream>
#include <fstream>

#include <boost/serialization/vector.hpp>

#include "Data.h"

ml::Data::Data(const std::vector<float>& d) : d(d)
{
}

ml::Data::Data(const Data& rhs)
{
    d = rhs.d;
}

ml::Data::Data()
{

}

ml::Data& ml::Data::operator=(const Data& rhs)
{
    d = rhs.d;

    return *this;
}

ml::Data ml::Data::Load(const std::string& filename)
{
    Data data;

    std::ifstream file(filename.c_str());

    boost::archive::text_iarchive ia(file);

    ia >> data;

    return data;
}

ml::Data::~Data()
{
}

void ml::Data::save(const std::string& filename)
{
    std::ofstream file(filename.c_str());    

    boost::archive::text_oarchive oa(file);

    oa << this;
}

std::vector<float> ml::Data::getD() const
{
   return d;
}

template<class Archive>
void ml::Data::serialize(Archive& ar, const unsigned int version)
{
   ar & d;

   std::cout << "Debug: " << d.size() << std::endl;
}

还有一个非常小的主程序:

#include <iostream>

#include "Data.h"

int main(int argc, char** argv)
{
    const std::string filename("./test.txt");
    const int limit = 100;

    std::vector<float> orig;
    std::vector<float> copy;

    for(int i=0; i<limit; ++i) {
        orig.push_back(i);
    }

    ml::Data origData(orig);
    origData.save(filename);

    ml::Data copyData = ml::Data::Load(filename);

    orig = origData.getD();
    copy = copyData.getD();

    std::cout << "Sizes: "    << std::endl;
    std::cout << "Original: " << orig.size() << std::endl;
    std::cout << "Copy: "     << copy.size() << std::endl;

    return 0;
}

程序输出为:

Debug: 100 
Debug: 0 
Sizes:  
Original: 100 
Copy: 0

序列化和文件输出似乎工作,生成的文件看起来如预期,但反序列化似乎失败。没有进一步的错误输出或任何提示,出了什么问题。如果感兴趣的话,Boost 版本是 1.60.0。

那么,你知道出了什么问题吗?

提前谢谢你。

【问题讨论】:

    标签: c++ serialization boost


    【解决方案1】:

    您的序列化将指针序列化:

    oa << this;
    

    反序列化反序列化为引用:

    Data data;
    ia >> data;
    

    这是一个错误。结果未定义。修复它:

    oa << *this;
    

    演示

    Live On Coliru

    打印:

    Debug (loading: false) 5
    Original: 5
    Debug (loading: true) 5
    Copy: 5
    

    代码:

    #ifndef DATA_H
    #define DATA_H
    
    #include <string>
    #include <vector>
    
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/archive/text_oarchive.hpp>
    
    namespace ml {
        class Data {
            private:
                std::vector<float> d;
    
                friend class boost::serialization::access;
    
                template<class Archive>
                void serialize(Archive& ar, const unsigned int version);
            public:
    
                static Data Load(const std::string& filename);
    
                Data(const std::vector<float>& d) : d(d) {}
                //Data(const Data& rhs) = default;
                Data() = default;
                //~Data() = default;
                //Data& operator=(const Data& rhs) = default;
    
                void save(const std::string& filename);
    
                std::vector<float> getD() const;
        };
    }
    #endif // DATA_H 
    
    #include <iostream>
    #include <fstream>
    
    #include <boost/serialization/vector.hpp>
    
    //#include "Data.h"
    ml::Data ml::Data::Load(const std::string& filename)
    {
        Data data;
    
        std::ifstream file(filename.c_str());
    
        boost::archive::text_iarchive ia(file);
    
        ia >> data;
    
        return data;
    }
    
    void ml::Data::save(const std::string& filename)
    {
        std::ofstream file(filename.c_str());    
    
        boost::archive::text_oarchive oa(file);
    
        oa << *this;
    }
    
    std::vector<float> ml::Data::getD() const
    {
       return d;
    }
    
    template<class Archive>
    void ml::Data::serialize(Archive& ar, const unsigned int /*version*/)
    {
       ar & d;
    
       std::cout << "Debug (loading: " << std::boolalpha << typename Archive::is_loading::type() << ") " << d.size() << std::endl;
    }
    
    #include <iostream>
    
    int main()
    {
        const std::string filename("./test.txt");
        const int limit = 5;
    
        {
            std::vector<float> orig;
    
            for(int i=0; i<limit; ++i) { orig.push_back(i); }
    
            ml::Data origData(orig);
            origData.save(filename);
    
            orig = origData.getD();
            std::cout << "Original: " << orig.size() << std::endl;
        }
    
        ml::Data copyData = ml::Data::Load(filename);
        std::cout << "Copy: " << copyData.getD().size() << std::endl;
    }
    

    【讨论】:

    • 谢谢,虽然很简单,但我看不到。现在可以了。
    猜你喜欢
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 2016-01-24
    • 2018-10-06
    • 2011-12-02
    • 1970-01-01
    • 2011-05-15
    • 1970-01-01
    相关资源
    最近更新 更多