2015-06-02 6 views
5

के लिए निजी डेटा सदस्यों को प्राप्त करें मैंने सदस्यों से पहुंचने के बाद से मेरे गैर-सदस्य serialize() फ़ंक्शन 'के लिए कक्षा A के प्राप्तकर्ताओं को प्रदान करने का प्रयास किया है।गैर घुसपैठ बूस्ट सीरियलाइजेशन सी ++

दुर्भाग्य से निष्पादन मुझे uncaught exception of type boost::archive::xml_archive_exception - Invalid XML tag name बता जब मैं ही टिककर खेल या तो GetRef() या GetId() उपयोग करने का प्रयास रहता है।
यह अच्छी तरह से काम करता है अगर मैं सार्वजनिक रूप से m_id तक पहुंचता हूं।

क्या ऐसा करने के कोई अच्छे तरीके हैं?

उत्तर

11
  1. आप पुराने जमाने मित्र उपयोग कर सकते हैं:

    Live On Coliru

    template <typename T> 
    class A { 
        public: 
        A(const T &id) : m_id(id) {} 
        private: 
        template <typename Ar, typename U> friend void boost::serialization::serialize(Ar&,A<U>&,const unsigned); 
        T m_id; 
    }; 
    
    namespace boost { 
    namespace serialization { 
        template <class Archive, typename T> 
        void serialize(Archive &ar, A<T> &a, const unsigned int) 
        { 
         ar & BOOST_SERIALIZATION_NVP(a.m_id); 
        } 
    } 
    } 
    

  2. आप getRef() दृष्टिकोण का उपयोग कर सकते हैं। यह

    • कोई मित्र (कम दखल)
    • की आवश्यकता है make_nvp (क्योंकि आप

    दुख की बात है एक XML तत्व नाम के रूप में a.getRef() उपयोग नहीं कर सकते, एक में संदर्भ गेटर तोड़ कैप्सूलीकरण होने की आवश्यकता है भयानक तरीका। मैं व्यक्तिगत रूप से m_id को पहले स्थान पर सार्वजनिक करना पसंद करता हूं, इसके बजाय

    Live On Coliru

    template <typename T> 
    class A { 
    public: 
        A(const T &id) : m_id(id) {} 
    
        T& getRef()    { return m_id; } 
        T const& getRef() const { return m_id; } 
    private: 
        T m_id; 
    }; 
    
    namespace boost { 
    namespace serialization { 
        template <class Archive, typename T> 
        void serialize(Archive &ar, A<T> &a, const unsigned int) 
        { 
         ar & boost::serialization::make_nvp("m_id", a.getRef()); 
        } 
    } 
    } 
    

    बोनस अंक:

  3. आप एक 'pimpl' शैली struct उपयोग कर सकते हैं। आप आगे A<> अंदर एक struct की घोषणा कर सकते हैं:

    template <typename T> 
    class A { 
    public: 
        struct access; 
    
        A(const T &id) : m_id(id) {} 
    private: 
        T m_id; 
    }; 
    

    कि getRef() दृष्टिकोण है जो बस कैप्सूलीकरण सभी तरह टूट जाता है तुलना में कम हस्तक्षेप है।अब आप इस वर्ग के भीतर निजी उपयोग छिपा सकते हैं:

    namespace boost { 
    namespace serialization { 
        template <class Archive, typename T> 
        void serialize(Archive &ar, A<T> &a, const unsigned int version) 
        { 
         A<T>::access::serialize(ar, a, version); 
        } 
    } 
    } 
    
    बेशक

    आप अभी भी इसे लागू करने की आवश्यकता है, लेकिन यह एक अलग शीर्षक में किया जा सकता है और वर्ग को प्रभावित नहीं करता एक <> (या के किसी भी इसके विशेषज्ञताओं) सब पर:

    template <typename T> 
    struct A<T>::access { 
        template <class Archive> 
        static void serialize(Archive &ar, A<T> &a, const unsigned int) { 
         ar & BOOST_SERIALIZATION_NVP(a.m_id); 
        } 
    }; 
    

    यह देखें Live On Coliru रूप में अच्छी तरह

+0

जोड़ा एक "सबसे अच्छा के- दोनों-दुनिया" दृष्टिकोण है कि कैप्सूलीकरण उल्लंघन नहीं करती है: ** [लाइव Coliru पर] (http://coliru.stacked-crooked.com/a/5d76b1aa22076a77) **। – sehe

+2

वाह। यह उनके पेशेवरों और विपक्ष के साथ विभिन्न समाधानों को दूर करने का एक बहुत अच्छा जवाब है। वास्तव में मैं क्या कर रहा था;)। धन्यवाद ! बहुत बुरा मैं दो बार मतदान नहीं कर सकता ... मैं 1/और 3/कोशिश करूंगा! – coincoin

+1

हमेशा के रूप में, एक पूर्ण महान जवाब। साथ ही, encapsulation तोड़ने, और संभवतः ट्रस्ट का पूरा उल्लंघन नहीं होने पर, [यह दृष्टिकोण दर्शाता है] (http://coliru.stacked-crooked.com/a/4424c219ee37aa20) निजी सदस्य चर को क्रमबद्ध करना। जैसा कि मैं कह सकता हूं उतना ही अच्छा है, यह spec अनुरूप है। तीसरे पक्ष के पुस्तकालयों से निपटने के दौरान मुझे दुख की बात है।): –

0
बस अतिरिक्त जानकारी के लिए

: में आदेश से sehe काम कर पहला समाधान पाने के लिए:

आप इस तरह मित्र विधि का एक आगे decleration की जरूरत है:

// Boost 
#include <boost/serialization/access.hpp> 

class ClassB; 

namespace boost{ 
namespace serialization { 
    template <typename Ar> void serialize(Ar&,ClassB&,const unsigned); 
} 
} 

class ClassB: public ClassA{ 

private: 
    template <typename Ar> friend void boost::serialization::serialize(Ar&,ClassA&,const unsigned); 
public: 
    ClassA(); 
    virtual ~ClassA(); 
}; 

मुझे थोड़ी देर के लिया यह काम कर पाने के।

चीयर्स

+0

वास्तव में, उस नमूना को काम करने के लिए, आप बस उस लिंक पर क्लिक करें जो कहता है ** ** [कॉलिरु पर लाइव] (http://coliru.stacked-crooked.com/a/1a0004c419ea0e37) ** और देखें कि आपको आवश्यकता नहीं है आगे की घोषणा – sehe

संबंधित मुद्दे