获取非侵入式升压系列化Ç私有数据成员++ [英] Get private data members for non intrusive boost serialization C++
问题描述
我曾尝试提供一流的干将 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
当它是公开的。
是否有这样做的任何好的方法呢?
-
您可以使用老式的朋友们:
<大骨节病> 住在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);
}
}
}
-
您可以使用
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());
}
}
}加分点:
-
您可以用'平普尔'式结构。你可以把里面声明一个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 ?
You can use good old-fashioned friends:
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); } } }
You can use the
getRef()
approach. This- requires no friends (less intrusive)
- requires
make_nvp
(because you can't usea.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.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:
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屋!