【发布时间】:2015-10-26 21:06:02
【问题描述】:
我想序列化下面的类,包装一个可以处理空 m_element 的指针,正如您在调用默认构造函数时所看到的那样。这跟在question之后。
template <typename T>
struct Ptr { // Ptr could use init constructor here but this is not the point
Ptr() { m_elem = 0; }
Ptr(const T* elem) {
if (elem)
m_elem = new T(*elem);
else
m_elem = 0;
}
Ptr(const T& elem)
{
m_elem = new T(elem);
}
Ptr(const Ptr& elem)
{
if (elem.m_elem)
m_elem = new T(*(elem.m_elem));
else
m_elem = 0;
}
virtual ~Ptr() { delete m_elem; m_elem = 0; };
const T& operator*() const { return *m_elem; };
T& operator*() { return *m_elem; };
const T* operator->() const { return m_elem; };
T* operator->() { return m_elem; };
T* m_elem;
};
namespace boost { namespace serialization {
// Not sure about the approach to manage null m_elem here
template<class Archive, class T>
void save(Archive & ar, const Ptr<T> &ptr, const unsigned int version)
{
T elem = 0;
if (ptr.m_elem != 0)
ar& boost::serialization::make_nvp("data", *ptr.m_elem);
else
ar& boost::serialization::make_nvp("data", elem);
}
// How to implement load ?
template<class Archive, class T>
void load(Archive & ar, Ptr<T> &ptr, const unsigned int version)
{
ar& boost::serialization::make_nvp("data", *ptr.m_elem);
}
template<class Archive, class T>
void serialize(Archive & ar, Ptr<T> &ptr, const unsigned int version)
{
boost::serialization::split_free(ar, ptr, version);
}
}} // end namespace
int main()
{
{
Ptr<A> p;
std::ostringstream oss;
boost::archive::xml_oarchive oa(oss);
oa << BOOST_SERIALIZATION_NVP(p);
std::cout << oss.str() << std::endl;
// segfault
Ptr<double> po;
std::istringstream iss;
iss.str(oss.str());
boost::archive::xml_iarchive ia(iss);
ia >> BOOST_SERIALIZATION_NVP(po);
}
{
Ptr<double> p(new double(2.0));
std::cout << *(p.m_elem) << std::endl;
std::ostringstream oss;
boost::archive::xml_oarchive oa(oss);
oa << BOOST_SERIALIZATION_NVP(p);
std::cout << oss.str() << std::endl;
// segfault
Ptr<double> po;
std::istringstream iss;
iss.str(oss.str());
boost::archive::xml_iarchive ia(iss);
ia >> BOOST_SERIALIZATION_NVP(po);
}
}
序列化似乎工作,但反序列化给出了段错误。我在 C++0x 中工作。
- 如果可能,如何在不更改 Ptr 的情况下提供安全的保存和加载功能来序列化 Ptr?
- 如果我需要修改Ptr,你有什么建议?
编辑:感谢 Jarod42 评论,我想出了以下保存/加载函数,使用布尔值来检测空指针与否。现在当m_elem 为空时我不再有段错误,但当它不为空时我有一个。
template<class Archive, class T>
void save(Archive & ar, const Ptr<T> &ptr, const unsigned int version)
{
bool is_null;
if (ptr.m_elem != 0) {
is_null = false;
ar& boost::serialization::make_nvp("is_null", is_null);
ar& boost::serialization::make_nvp("data", *ptr.m_elem);
}
else
{
is_null = true;
ar& boost::serialization::make_nvp("is_null", is_null);
}
}
template<class Archive, class T>
void load(Archive & ar, Ptr<T> &ptr, const unsigned int version)
{
bool is_null;
ar& boost::serialization::make_nvp("is_null", is_null);
if (is_null == true) {
ptr.m_elem = 0;
}
else
{
ar& boost::serialization::make_nvp("data", *ptr.m_elem);
}
}
【问题讨论】:
-
您应该序列化一个布尔值以了解指针是否为 nullptr(如果不是,也序列化其内容)。对于加载,检索此布尔值并在需要加载时分配一个默认元素。
-
谢谢 Jarod42 我会尝试实施这个解决方案
-
现在反序列化适用于空指针,但
new double测试用例出现段错误。 Live on Coliru -
呃。这个问题与stackoverflow.com/questions/31180311/… 有何不同?
-
我无法使反序列化正常工作,因此提出了这个新问题。
标签: c++ serialization boost boost-serialization