获取非侵入式升压系列化Ç私有数据成员++ [英] Get private data members for non intrusive boost serialization C++

查看:192
本文介绍了获取非侵入式升压系列化Ç私有数据成员++的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我曾尝试提供一流的干将 A 我非会员连载() function`因为访问成员是私有的。

 模板< typename的T>
A级
{
上市:
  A(const的T&安培; ID):m_id(ID){}
  夯; getRef(){返回m_id; } //不给了良好的效果
  ŧ的getId(){返回m_id; } //不给了良好的效果
  常量T&安培; getRef()const的{返回m_id; } //不给了良好的效果
私人://我想保持私人
  Ťm_id;
}名字空间boost {空间序列{模板<等级档案,类型名T>
无效连载(归档和放大器; AR,A和A,const的无符号整型版)
{
    // AR&放大器; BOOST_SERIALIZATION_NVP(a.m_id); //我想避免它的工作原理,如果m_id是公开
    AR&放大器; BOOST_SERIALIZATION_NVP(a.GetRef()); // 我要这个 !
}}}//后来我用
的std :: OFS的ofstream(的test.xml);
提高::档案:: xml_oarchive OA(OFS);
A< INT>一个(42);
OA<< BOOST_SERIALIZATION_NVP(一);

不幸的是,执行不断告诉我类型为boost未捕获的异常::档案:: xml_archive_exception - 无效的XML标记名称当我尝试使用既干将 GetRef() GETID()。结果
它工作得很好,如果我直接进入 m_id 当它是公开的。

是否有这样做的任何好的方法呢?


解决方案

  1. 您可以使用老式的朋友们:

    <大骨节病> 住在Coliru

     模板&LT; typename的T&GT;
    A级{
      上市:
        A(const的T&安培; ID):m_id(ID){}
      私人的:
        模板&LT; typename的氩气,typename的U&GT;朋友无效的boost ::序列::序列化(AR&安培;,A&LT; U&GT;&安培;,const的无符号);
        Ťm_id;
    };名字空间boost {
    命名空间序列{
        模板&LT;等级档案,类型名T&GT;
        无效连载(归档和放大器; AR,读取&lt; T&GT;&放大器;一,const的无符号整数)
        {
            AR&安培; BOOST_SERIALIZATION_NVP(a.m_id);
        }
    }
    }



  2. 您可以使用 getRef()办法。这


    • 要求没有朋友(较少干扰)

    • 要求 make_nvp (因为你不能使用 a.getRef()作为XML元素名称


      

    不幸的是,在有一个可怕的方式参考吸气破坏封装。我个人preFER有 m_id 公开摆在首位,而不是


    <大骨节病> 住在Coliru

     模板&LT; typename的T&GT;
    A级{
    上市:
        A(const的T&安培; ID):m_id(ID){}    夯; getRef(){返回m_id; }
        ŧ常量和放大器; getRef()const的{返回m_id; }
    私人的:
        Ťm_id;
    };名字空间boost {
    命名空间序列{
        模板&LT;等级档案,类型名T&GT;
        无效连载(归档和放大器; AR,读取&lt; T&GT;&放大器;一,const的无符号整数)
        {
            AR&安培;升压::序列:: make_nvp(m_id,a.getRef());
        }
    }
    }

    加分点:


  3. 您可以用'平普尔'式结构。你可以把里面声明一个struct A&LT;&GT;

     模板&LT; typename的T&GT;
    A级{
    上市:
        结构的访问;    A(const的T&安培; ID):m_id(ID){}
    私人的:
        Ťm_id;
    };

    这比它只是打破了封装一路 getRef()办法侵扰程度较低。现在,你可以隐藏这个类里面的私有访问:

     名字空间boost {
    命名空间序列{
        模板&LT;等级档案,类型名T&GT;
        无效连载(归档和放大器; AR,读取&lt; T&GT;&放大器;一,const的无符号整型版)
        {
            A&LT; T&GT; ::访问::连载(AR,一个版本);
        }
    }
    }

    当然,你仍然需要实现它,但是这可以在一个单独的头进行,并不会影响A类&LT;在所有>(或其任何专业的):

     模板&LT; typename的T&GT;
    结构A&LT; T&GT; :: {访问
        模板&LT;类归档和GT;
        静态无效连载(归档和放大器; AR,读取&lt; T&GT;&放大器;一,const的无符号整数){
            AR&安培; BOOST_SERIALIZATION_NVP(a.m_id);
        }
    };

    看它的 住在Coliru 以及


I have tried providing getters of class A for my non-member serialize() function` since accessing from members is private.

template<typename T>
class A
{
public:
  A(const T& id) : m_id(id) {}
  T& getRef() { return m_id; } // not giving good results
  T  getId()  { return m_id; } // not giving good results
  const T& getRef() const { return m_id; } // not giving good results
private: // I would like to keep it private
  T m_id;
}

namespace boost { namespace serialization {

template<class Archive,typename T>
void serialize(Archive &ar, A &a, const unsigned int version)
{
    // ar &BOOST_SERIALIZATION_NVP(a.m_id); // I would like to avoid that it works if m_id is public
    ar &BOOST_SERIALIZATION_NVP(a.GetRef()); // I want this !
}

}}

// and later I use
std::ofstream ofs("test.xml");
boost::archive::xml_oarchive oa(ofs);
A<int> a(42);
oa << BOOST_SERIALIZATION_NVP(a);

Unfortunately the execution keeps telling me uncaught exception of type boost::archive::xml_archive_exception - Invalid XML tag name when I try to use getters either GetRef()or GetId().
It works well if I access directly to m_id when it is public.

Are there any nice ways of doing so ?

解决方案

  1. You can use good old-fashioned friends:

    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. You can use the getRef() approach. This

    • requires no friends (less intrusive)
    • requires make_nvp (because you can't use a.getRef() as an XML element name

    Sadly, having the reference getter break encapsulation in a horrific way. I'd personally prefer to have m_id public in the first place, instead.

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

    Bonus points:

  3. You can use a 'pimpl' style struct. You can forward declare a struct inside A<>:

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

    That's less intrusive than the getRef() approach which simply breaks encapsulation all the way. Now, you can hide the private access inside this class:

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

    Of course you still need to implement it, but this can be done in a separate header and doesn't influence class A<> (or any of its specializations) at all:

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

    See it Live On Coliru as well

这篇关于获取非侵入式升压系列化Ç私有数据成员++的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆