【问题标题】:boost serialiaze input stream error提升序列化输入流错误
【发布时间】:2015-07-22 17:52:08
【问题描述】:

我正在研究一个简单的序列化类。我一直在输入流上抛出异常。我将以下示例放在一起,以简单的方式说明我试图完成的工作。

我有一个简单的 boost 序列化示例,但我遇到了异常:

#include <boost/serialization/serialization.hpp> 
#include <boost/archive/text_oarchive.hpp> 
#include <boost/archive/text_iarchive.hpp> 
#include <boost/serialization/export.hpp> 
#define NVP(X) X 

class base { 
public: 
friend class boost::serialization::access; 
base (){ v1 = 10;} 
int v1; 
template<class Archive> 
void serialize(Archive & ar, const unsigned int file_version) 
{ 

    ar & NVP(v1); 
} 
virtual void bla()=0; 
}; 


class derived : public base { 
public: 
friend class boost::serialization::access; 
int v2 ; 
derived() { v2 = 100;} 
template<class Archive> 
void serialize(Archive & ar, const unsigned int file_version){ 
    boost::serialization::base_object<base>(* this); 
    ar & NVP(v2); 
} 

virtual void bla(){};
};
BOOST_CLASS_EXPORT(base);
BOOST_CLASS_EXPORT_GUID(derived, "derived");

int main ( )
{
std::stringstream ss;
boost::archive::text_oarchive ar(ss);
base *b = new derived();
ar << NVP(b);
std::cout << ss.str()<<std::endl;



std::istringstream ssi;
base *b1 = new derived();
{
boost::archive::text_iarchive ar1(ssi);
ar1 >> b1;
}
//std::cout << ssi.str();
std::cout << "v1: " << b1->v1 << std::endl;

}

我得到的例外是:

terminate called after throwing an instance of 'boost::archive::archive_exception'
  what():  input stream error

任何帮助将不胜感激。

【问题讨论】:

    标签: c++ serialization boost


    【解决方案1】:

    您正在从一个空流中读取:

    std::istringstream ssi;
    // ...
    boost::archive::text_iarchive ar1(ssi);
    

    另外,你泄露了这个对象:

    base *b1 = new derived();
    

    这是一个固定的例子,注意:

    • 在使用流式数据之前关闭存档是非常好的做法/很重要
    • BOOST_CLASS_EXPORT_GUID(derived, "derived") 不添加任何超出 BOOST_CLASS_EXPORT(derived) 的内容
    • 您可以有条件地打印 v2:

      if (auto* d = dynamic_cast<derived*>(b1))
          std::cout << "v2: " << d->v2 << std::endl;
      
    • 我以bla() 为例来打印值

    • NVP() 有点不确定。为什么不把它留给未标记的档案(即 XML 以外的档案)?如果您打算支持 XML,只需使用 BOOST_SERIALIZATION_NVPboost::serialization::make_nvp 等即可。

    • std::cout &lt;&lt; "v2: " &lt;&lt; b1-&gt;v2 &lt;&lt; std::endl; 完全不合适

    • 只需将b1 初始化为null,这样就不会泄露它;记得释放所有指针(使用智能指针!)

    • public:friend 在你的类型中的混合并没有多大意义

    Live On Coliru

    #include <boost/serialization/serialization.hpp>
    #include <boost/archive/text_oarchive.hpp>
    #include <boost/archive/text_iarchive.hpp>
    #include <boost/serialization/export.hpp>
    #include <sstream>
    
    class base {
      public:
        base(int v1) : v1(v1) {}
        virtual void bla() const = 0;
    
      private:
        friend class boost::serialization::access;
    
        template <class Archive> void serialize(Archive &ar, unsigned /*int const file_version*/) {
            ar & BOOST_SERIALIZATION_NVP(v1);
        }
      protected:
        int v1;
    };
    
    class derived : public base {
      public:
        derived(int v1 = 10, int v2 = 100) : base(v1), v2(v2) {}
        virtual void bla() const {
            std::cout << "v1: " << v1 << ", v2: " << v2 << "\n";
        }
    
      private:
        friend class boost::serialization::access;
        int v2;
        template <class Archive> void serialize(Archive &ar, unsigned /*int const file_version*/) {
            boost::serialization::base_object<base>(*this);
            ar & BOOST_SERIALIZATION_NVP(v2);
        }
    };
    
    BOOST_CLASS_EXPORT(base)
    BOOST_CLASS_EXPORT(derived)
    
    int main() {
        std::stringstream ss;
        {
            boost::archive::text_oarchive ar(ss);
            base *b = new derived();
            ar << boost::serialization::make_nvp("base", b);
    
            delete b; // TODO use RAII instead
        }
    
        std::cout << ss.str() << std::endl;
        base *deserialized = nullptr;
        {
            boost::archive::text_iarchive ar1(ss);
            ar1 >> boost::serialization::make_nvp("base", deserialized);
        }
    
        deserialized->bla();
        delete deserialized;
    }
    

    打印

    22 serialization::archive 12 0 7 derived 1 0
    0 100
    
    v1: 10, v2: 100
    

    【讨论】:

    • 谢谢先生。这是一个过于接近示例的情况。现在我看到我的流实际上没有任何东西可以反序列化。
    • 我刚刚意识到我没有警告delete-ing deserialized anyways。所以,add that to the list :)
    • 谢谢。稍后我会再给你一个。在我的实际项目中,我仍然收到输入流错误异常。我现在正在努力简化问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-08
    • 1970-01-01
    • 1970-01-01
    • 2018-04-14
    • 2016-05-05
    • 1970-01-01
    相关资源
    最近更新 更多