继承模板类的boost :: serialization

时间:2014-01-20 14:15:26

标签: c++ templates serialization boost virtual

我有一个虚拟模板类和一个派生类。我现在正在尝试对派生类使用boost :: serialization。到目前为止,这是我的代码:

template <class T> class classOne { 
public:     
    classOne(){};   
    classOne(T val) : st(val){};    
    virtual ~classOne() {};     
    virtual double GetError() =0; 
protected:  T st;
private:
    friend class boost::serialization::access;
    template<class archive>
    void serialize(archive& ar, const unsigned int version)
    {
         ar & BOOST_SERIALIZATION_NVP(st);
    }
}; 
BOOST_SERIALIZATION_ASSUME_ABSTRACT(classOne<double>);

template <class T> class classTwo : public classOne<T>
{
public:
    classTwo() : classOne<T>(1.0), error(0){};
    classTwo(T val) : classOne<T>(val), error(val){};
    virtual T GetError() {return error;};

private:
    T error;
    friend class boost::serialization::access;
    template<class archive>
    void serialize(archive& ar, const unsigned int version)
    {
            ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(classOne<T>);
            ar & BOOST_SERIALIZATION_NVP(error);
    }
};
int main(int argc, char** argv){
   classTwo<double> ch2(0.5);
   std::ofstream ofs2("test2.xml");
   boost::archive::xml_oarchive oa2(ofs2);
   oa2 << BOOST_SERIALIZATION_NVP(ch2);
   ofs2.close();
}

代码编译但在运行时我得到:

terminate called after throwing an instance of 'boost::archive::xml_archive_exception'
    what():  Invalid XML tag name

当classOne不是模板类时,一切正常。有人可以帮忙吗?

1 个答案:

答案 0 :(得分:1)

嗯,问题很明显:<>在XML元素标签内部不顺利。

所以,这就是我天真地想到要解决的问题。

<击>

<击>
ar & boost::serialization::make_nvp(
      "base", static_cast<classOne<T>&>(*this));

<击>

重要更新然而,就在今天,我偶然发现了这里的文档:

  

请注意派生类中基类的序列化。 不要直接调用基类序列化函数。这样做似乎可行,但会绕过跟踪写入存储的实例的代码,以消除冗余。它还将绕过将类版本信息写入存档。因此,建议始终将成员序列化函数设为私有。

糟糕。所以这是新的正确建议:

    typedef classOne<T> baseClass;
    ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(baseClass);

现在,您可以通过使用宏并使用typedef隐藏括号来控制xml元素的名称。

输出:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE boost_serialization>
<boost_serialization signature="serialization::archive" version="10">
<ch2 class_id="0" tracking_level="0" version="0">
    <baseClass class_id="1" tracking_level="0" version="0">
        <st>0.5</st>
    </baseClass>
<error>0.5</error>
</ch2>