获取非侵入式升级序列化C的私有数据成员

我尝试为我的非成员serialize()函数提供A类的getter,因为从成员访问是私有的.
template<typename T>
class A
{
public:
  A(const T& id) : m_id(id) {}
  T& getRef() { return m_id; } // not giving good results
  T  getId()  { return m_id; } // not giving good results
  const T& getRef() const { return m_id; } // not giving good results
private: // I would like to keep it private
  T m_id;
}

namespace boost { namespace serialization {

template<class Archive,typename T>
void serialize(Archive &ar,A &a,const unsigned int version)
{
    // ar &BOOST_SERIALIZATION_NVP(a.m_id); // I would like to avoid that it works if m_id is public
    ar &BOOST_SERIALIZATION_NVP(a.GetRef()); // I want this !
}

}}

// and later I use
std::ofstream ofs("test.xml");
boost::archive::xml_oarchive oa(ofs);
A<int> a(42);
oa << BOOST_SERIALIZATION_NVP(a);

不幸的是,执行时一直告诉我类型为boost :: archive :: xml_archive_exception的未捕获异常 – 当我尝试使用getList(GetRef()或GetId()时,无效的XML标记名称.
如果我公开时直接访问m_id,它的效果很好.

这样做有什么好方法吗?

解决方法

>你可以使用老朋友:

Live On Coliru

template <typename T>
class A {
  public:
    A(const T &id) : m_id(id) {}
  private:
    template <typename Ar,typename U> friend void boost::serialization::serialize(Ar&,A<U>&,const unsigned);
    T m_id;
};

namespace boost {
namespace serialization {
    template <class Archive,typename T>
    void serialize(Archive &ar,A<T> &a,const unsigned int)
    {
        ar & BOOST_SERIALIZATION_NVP(a.m_id);
    }
}
}

>您可以使用getRef()方法.这个

>不需要朋友(少打扰)
>需要make_nvp(因为您不能使用a.getRef()作为XML元素名称

Sadly,having the reference getter break encapsulation in a horrific way. I’d personally prefer to have m_id public in the first place,instead.

Live On Coliru

template <typename T>
class A {
public:
    A(const T &id) : m_id(id) {}

    T& getRef()             { return m_id; } 
    T const& getRef() const { return m_id; } 
private:
    T m_id;
};

namespace boost {
namespace serialization {
    template <class Archive,const unsigned int)
    {
        ar & boost::serialization::make_nvp("m_id",a.getRef());
    }
}
}

奖励积分:
>您可以使用’pimpl’样式结构.您可以在A<>内转发声明一个结构:

template <typename T>
class A {
public:
    struct access;

    A(const T &id) : m_id(id) {}
private:
    T m_id;
};

这比getRef()方法更少侵入,getRef()方法只是简单地破坏了封装.现在,您可以隐藏此类中的私有访问:

namespace boost {
namespace serialization {
    template <class Archive,const unsigned int version)
    {
        A<T>::access::serialize(ar,a,version);
    }
}
}

当然,您仍然需要实现它,但这可以在单独的标题中完成,并且不会影响A类<> (或其任何专业):

template <typename T>
struct A<T>::access {
    template <class Archive>
    static void serialize(Archive &ar,const unsigned int) {
        ar & BOOST_SERIALIZATION_NVP(a.m_id);
    }
};

另见Live On Coliru

相关文章

本程序的编译和运行环境如下(如果有运行方面的问题欢迎在评...
水了一学期的院选修,万万没想到期末考试还有比较硬核的编程...
补充一下,先前文章末尾给出的下载链接的完整代码含有部分C&...
思路如标题所说采用模N取余法,难点是这个除法过程如何实现。...
本篇博客有更新!!!更新后效果图如下: 文章末尾的完整代码...
刚开始学习模块化程序设计时,估计大家都被形参和实参搞迷糊...