2009-11-06 107 views
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*/); 
... 
} 
+0

thanx的答案 – dodol 2009-11-06 14:08:31

回答

3

像任何其他非成員函數,你的序列化功能只能訪問NetElement的公共成員。如果像往常一樣,公共接口沒有公開足夠的狀態來序列化對象,那麼您需要將serialize函數作爲成員。

在這種情況下,雖然國家是受保護的,因此你可以使用從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; 
} 

缺點是,這種複製連載之前的對象。

+0

確定,但如果NetElement類不能改變什麼?我有什麼選擇?對不起,還不夠清楚... thanx爲快速回答,但... – dodol 2009-11-06 13:38:28

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