增强对受保护数据的序列化访问

发布于 2024-08-09 18:39:06 字数 801 浏览 3 评论 0原文

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

When I try to serialize class with protected members, I get the following errors:
"cannot access protected member declared in class NetElement". The idea is that I'd like to have one serialization function outside of class definition. What am I doing wrong?

best regards,
mightydodol


Here is the code...

// 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*/);
 ...
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

浅唱々樱花落 2024-08-16 18:39:06

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

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

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

You already show yourself changing the class by adding the "friend" line (which does nothing for you without the serialize function being inside the class).

Without being able to change the class, you are stuck with more fragile solutions (here is one I had to do once, that I'm not proud of (but it does show the whole point of protected over private))

#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);
}
这样的小城市 2024-08-16 18:39:06

与任何其他非成员函数一样,您的序列化函数只能访问 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;
}

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

Like any other non-member function, your serialize function can only access the public members of NetElement. If, as is often the case, the public interface doesn't expose enough state to serialize the object, then you'll need to make the serialize function a member.

In this case, though, the state is protected, so you could get to it using an "accessor" class derived from 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;
}

The downside is that this copies the object before serialising it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文