2

保護されたメンバーを使用してクラスをシリアル化しようとすると、「クラスNetElementで宣言された保護されたメンバーにアクセスできません」というエラーが発生します。クラス定義の外に1つのシリアル化関数が欲しいという考えです。私は何が間違っているのですか?

よろしく、マイティドドール


これがコードです...

// 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

「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);
}
于 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 に答える