2

当我尝试使用受保护成员序列化类时,出现以下错误:“无法访问在类 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*/);
 ...
}
4

2 回答 2

5

您已经通过添加“朋友”行来展示自己更改类(如果类中没有序列化函数,这对您没有任何作用)。

如果无法更改课程,您将陷入更脆弱的解决方案(这是我不得不做的一次,我并不为此感到自豪(但它确实显示了保护而不是私有的全部意义))

#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);
}
于 2009-11-06T13:54:36.840 回答
3

与任何其他非成员函数一样,您的序列化函数只能访问 NetElement 的公共成员。如果通常情况下,公共接口没有公开足够的状态来序列化对象,那么您需要使序列化函数成为成员。

但是,在这种情况下,状态是受保护的,因此您可以使用从 NetElement 派生的“访问器”类来访问它:

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;
}

缺点是这会在序列化之前复制对象。

于 2009-11-06T13:33:20.747 回答