增强序列化:未调用 save_construct_data

Posted

技术标签:

【中文标题】增强序列化:未调用 save_construct_data【英文标题】:boost serialization: save_construct_data not called 【发布时间】:2015-07-06 21:53:04 【问题描述】:

我正在使用 boost 来序列化没有默认构造函数的对象,但是我遇到了一个奇怪的问题:save_construct_data 没有被调用!

下面是重现此问题的示例程序:

main.cpp

#include <vector>
#include <iostream>
#include "Test.h"

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

int main()

    using T = float;
    walid::Test<T> instance ( 2, 2.3f, -0.5f ) ;

    std::ofstream ofs ( "data" );
    boost::archive::text_oarchive oa ( ofs );    
    oa << instance;   

测试.h

#ifndef __Test_HEADER__
#define __Test_HEADER__

#include <list>
#include <vector>
#include <iostream>
#include <initializer_list>

namespace walid
 
    template<typename T>
    class Test
    
      public:
        std::vector<T> elements;
    int in_dim ;

    Test(int input_dim, std::initializer_list<T> elem)
    
      in_dim = input_dim;
      elements = std::vector<T>(elem);
    
    void start();
    void stop();
    ;


#include "Test_serialization.inl"

#endif

最后是 Test_serialization.inl

namespace boost 
namespace serialization 

    template<class Archive, class T>
    inline void serialize(Archive & ar, walid::Test<T>& t, const unsigned int version)
    
      std::cout<<"serialize Test ..."<<std::endl;
    

    template<class Archive, class T>
    inline void save_construct_data ( Archive & ar, const walid::Test<T>* t, const unsigned int version )
    
        std::cout<<"call save_construct_data Test ..."<<std::endl;

    

    template<class Archive, class T>
    inline void load_construct_data ( Archive & ar, walid::Test<T>* t, const unsigned int version )
    
        std::cout<<"call load_construct_data Test ..."<<std::endl;
        ::new ( t ) walid::Test<T> ( 2, 2.3f, -0.5f ) ;
    


这段代码应该打印出来:

serialize Test ... 
call save_construct_data Test ...

但它只打印serialize Test ...(不调用save_construct_data)

我错过了什么吗?

感谢您的帮助。

【问题讨论】:

【参考方案1】:

假设您正在构建walid::Test&lt;T&gt;

但是,如果你仔细观察,你会发现你实际上并没有构建任何东西。

根据设计,Boost 序列化(反)序列化(成)左值。反序列化过程中唯一需要构造的地方是序列化动态分配的对象时。

您可以通过将实例的存储更改为例如shared_ptr:

Live On Coliru

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

#include <boost/shared_ptr.hpp>

int main()

    using T = float;
    using Test = walid::Test<T>;

    
        boost::shared_ptr<Test> shared_instance(new Test(2, 2.3f, -0.5f));

        std::ofstream ofs("data");
        boost::archive::text_oarchive oa(ofs);
        oa << shared_instance;
    

    
        boost::shared_ptr<Test> deserialized;

        std::ifstream ifs("data");
        boost::archive::text_iarchive ia(ifs);
        ia >> deserialized;
    

打印

call save_construct_data Test ...
serialize Test ...
call load_construct_data Test ...
serialize Test ...

【讨论】:

感谢您的帮助,它可以工作,但是在尝试反序列化 boost::shared_ptr new_instance; 时会崩溃; std::ifstream ifs ( "数据" ); boost::archive::text_iarchive ia ( ifs ); ia >> new_instance; @boussaffa 这对我来说不会失败:Live On Coliru。也许您正在做其他不同的事情(例如,您是否忘记在反序列化之前刷新/关闭数据 + oa?)。

以上是关于增强序列化:未调用 save_construct_data的主要内容,如果未能解决你的问题,请参考以下文章

未调用序列化函数

Django 序列化程序:未调用验证函数

PHP面向对象----- 魔术方法

护照反序列化用户未在帆中调用

如何识别c__DisplayClass未标记为可序列化的位置

Python mixin/decorator/__metaclass__ 用于基类增强