当我尝试使用受保护的成员序列化类时,我收到以下错误: “无法访问类NetElement中声明的受保护成员”。我的想法是,我希望在类定义之外有一个序列化函数。我究竟做错了什么?
最好的问候, mightydodol
这是代码......
// class definition
class NetElement
{
friend class boost::serialization::access;
protected:
int nelements;
int ids;
public:
static NetElement* New(){return new NetElement;}
virtual void Delete(){delete this;}
protected:
NetElement(){};
~NetElement(){};
};
// nonintrusive serialize
template<class Archive>
void serialize(Archive & ar, NetElement& element, const unsigned int version=1)
{
ar & element.nelements & element.ids;
}
int main(void)
{...
std::ofstream os("Pipe1.txt");
boost::archive::text_oarchive oa(os);
serialize(oa,el/*ref to NetElementObj*/);
...
}
答案 0 :(得分:5)
您已经通过添加“朋友”行来显示自己正在更改类(如果没有序列化函数在类中,则无法为您做任何事情)。
如果不能改变课程,你就会陷入更脆弱的解决方案(这是我必须做的一次,我不为之骄傲(但它确实显示了保护私人的全部意义))< / p>
#include <boost/archive/text_oarchive.hpp>
#include <fstream>
// class definition
class NetElement
{
protected:
int nelements;
int ids;
public:
static NetElement* New(){return new NetElement;}
virtual void Delete(){delete this;}
protected:
NetElement(){};
~NetElement(){};
};
class NetElementS : public NetElement
{
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive & ar, const unsigned int version)
{
ar & nelements & ids;
}
};
int main(void)
{
NetElement *el = NetElement::New();
std::ofstream os("Pipe1.txt");
boost::archive::text_oarchive oa(os);
oa & *reinterpret_cast<NetElementS *>(el);
}
答案 1 :(得分:3)
与任何其他非成员函数一样,您的序列化函数只能访问NetElement的公共成员。如果通常情况下,公共接口没有公开足够的状态来序列化对象,那么您需要使序列化函数成为成员。
在这种情况下,状态是受保护的,因此您可以使用从NetElement派生的“accessor”类来实现它:
class NetElementAccessor : private NetElement
{
public:
explicit NetElementAccessor(const NetElement &e) : NetElement(e) {}
using NetElement::nelements;
using NetElement::ids;
};
template<class Archive>
void serialize(Archive & ar, NetElement& element, const unsigned int version=1)
{
NetElementAccessor accessor(element);
ar & accessor.nelements & accessor.ids;
}
缺点是它会在序列化之前复制对象。