如何用boost::serialization去序列化派生模板类(续)
在
如何用boost::serialization去序列化派生模板类这篇文章中,介绍了序列化派生类模板类,
在写測试用例时一直出现编译错误,调了非常久也没跳出来,今天偶然试了一下...竟然调了出来。
先看看变异错误的代码(。。。看不出有错,但是编译就有错)。
基类代码:
class base_class
{
public:
base_class(int m=0) : base_member_(0) {}
virtual ~base_class() {}
virtual void print_data() = 0;
private:
class boost::serialization::access;//#1
template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version)//#2
{
ar & BOOST_SERIALIZATION_NVP(base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
protected:
int base_member_;
//other member...
};
依照前面几篇的列子:
class base_class
{
public:
base_class(int m=0) : base_member_(0) {}
virtual ~base_class() {} virtual void print_data() = 0; private:
class boost::serialization::access;//#1
template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version)//#2
{
ar & BOOST_SERIALIZATION_NVP(base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
} protected:
int base_member_;
//other member...
};
依照前面几篇的列子:
#1应该声明为友元类(不知道为什么,看看这篇文章boost::serialization
拆分serialize函数)。
#2实现一个serialize函数。这应该没问题???????但是却又问题。后面就知
道了。
然后来看看派生模板类的代码:
template<typename T>//#1
class divided_class : public base_class
{
public:
divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
virtual ~divided_class() {}
virtual void print_data()
{
std::cout << base_member_ << " "
<< diveded_member_ << " ";
}
private:
class boost::serialization::access;//#2
template<typename Archive>
void serialize(Archive& ar, const unsigned int file_version)//#3
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
ar & BOOST_SERIALIZATION_NVP(diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
private:
T diveded_member_;
//other member....
};
#1 diveide_class 是一个模板派生类
template<typename T>//#1
class divided_class : public base_class
{
public:
divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
virtual ~divided_class() {} virtual void print_data()
{
std::cout << base_member_ << " "
<< diveded_member_ << " ";
} private:
class boost::serialization::access;//#2
template<typename Archive>
void serialize(Archive& ar, const unsigned int file_version)//#3
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
ar & BOOST_SERIALIZATION_NVP(diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
} private:
T diveded_member_;
//other member....
};
#1 diveide_class 是一个模板派生类
#2 声明友元类
#3 实现派生类的serialize函数
这样写应该也没问题。
好,接下来写个save()函数測试一下:
void save()
{
std::ofstream ofs("t8.xml");
boost::archive::xml_oarchive oa(ofs);
base_class* int_base = new divided_class<int>(1, 3);
base_class* str_base = new divided_class<std::string>(1, "wyp");
base_class* float_base = new divided_class<float>(1, 3.1415926f);
//Now the tricky point is to register class in serialize
oa.template register_type<divided_class<int>>(NULL);
oa.template register_type<divided_class<std::string>>(NULL);
oa.template register_type<divided_class<float>>(NULL);
//begin serialize
oa & BOOST_SERIALIZATION_NVP(int_base);
oa & BOOST_SERIALIZATION_NVP(str_base);
oa & BOOST_SERIALIZATION_NVP(float_base);
//delete pointer ...
}
{
std::ofstream ofs("t8.xml");
boost::archive::xml_oarchive oa(ofs); base_class* int_base = new divided_class<int>(1, 3);
base_class* str_base = new divided_class<std::string>(1, "wyp");
base_class* float_base = new divided_class<float>(1, 3.1415926f); //Now the tricky point is to register class in serialize
oa.template register_type<divided_class<int>>(NULL);
oa.template register_type<divided_class<std::string>>(NULL);
oa.template register_type<divided_class<float>>(NULL); //begin serialize
oa & BOOST_SERIALIZATION_NVP(int_base);
oa & BOOST_SERIALIZATION_NVP(str_base);
oa & BOOST_SERIALIZATION_NVP(float_base); //delete pointer ...
}
在main函数中条用这个save函数。
编译器会出现几个错误:
Error 1 error C2248: 'T88::divided_class<T>::serialize' : cannot access private member declared in class 'T88::divided_class<T>' d:\sdk\boost_1_53_0\boost\serialization\access.hpp 118
Error 2 error C2248: 'T88::divided_class<T>::serialize' : cannot access private member declared in class 'T88::divided_class<T>' d:\sdk\boost_1_53_0\boost\serialization\access.hpp 118
...
Error 2 error C2248: 'T88::divided_class<T>::serialize' : cannot access private member declared in class 'T88::divided_class<T>' d:\sdk\boost_1_53_0\boost\serialization\access.hpp 118
...
就是派生类的serialize不能訪问私有数据。非常诡异!
serialize本来就是派生类的成员函数,并且access类还声明为友元类(access 要调用派生类的serialize)。不知道为什么?求解。。。。。。。
找不出就换了一种方法,上面的serialize函数intrusive式,就换成一种non-intrusive式的,
由于非入侵式的没有this指针:
template<typename Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);//#1
ar & BOOST_SERIALIZATION_NVP(diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
void serialize(Archive& ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);//#1
ar & BOOST_SERIALIZATION_NVP(diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
#1这个宏中包括一个this指针,因此这个仅仅能留在类里面,就是定义一个函数条用这个宏:
template<typename Archive>
void serialize_base_class(Archive& ar)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
}
void serialize_base_class(Archive& ar)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
}
然后声明派生模板类的友元函数serialize:
template<typename Archive, typename TT>
friend void serialize(Archive& ar, divided_class<TT>& divcls, const unsigned int file_version);
friend void serialize(Archive& ar, divided_class<TT>& divcls, const unsigned int file_version);
接着就是在类的外面实现这个函数:
template<typename Archive, typename T>
void serialize(Archive& ar, divided_class<T>& discls, const unsigned int file_version)
{
discls.serialize_base_class(ar);//条用序列化基类的成员函数
ar & BOOST_SERIALIZATION_NVP(discls.diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
void serialize(Archive& ar, divided_class<T>& discls, const unsigned int file_version)
{
discls.serialize_base_class(ar);//条用序列化基类的成员函数
ar & BOOST_SERIALIZATION_NVP(discls.diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
这样应该解决这个问题了,编译。。。。
果然攻克了派生类的问题,但是基类却出现了和派生了一样的问题:
Error 2 error C2248: 'T88::base_class::serialize' : cannot access private member declared in class 'T88::base_class' d:\sdk\boost_1_53_0\boost\serialization\access.hpp 118
仅仅能才去相同的方法来解决:
private:
/*
class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}*
*/
template<typename Archive>
friend void serialize(Archive& ar, base_class& bascls, const unsigned int file_version);
在类外面:
template<typename Archive>
void serialize(Archive& ar, base_class& bascls, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(bascls.base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
/*
class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}*
*/
template<typename Archive>
friend void serialize(Archive& ar, base_class& bascls, const unsigned int file_version); 在类外面:
template<typename Archive>
void serialize(Archive& ar, base_class& bascls, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(bascls.base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
编译执行果然解决这个问题!
但是如今还是不知道原来的代码有什么错误!
正确的測试列子代码例如以下:
class base_class
{
public:
base_class(int m=0) : base_member_(0) {}
virtual ~base_class() {}
virtual void print_data() = 0;
private:
template<typename Archive>
friend void serialize(Archive& ar, base_class& bascls, const unsigned int file_version);
protected:
int base_member_;
//other member...
};
template<typename Archive>
void serialize(Archive& ar, base_class& bascls, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(bascls.base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
template<typename T>
class divided_class : public base_class
{
public:
divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
virtual ~divided_class() {}
virtual void print_data()
{
std::cout << base_member_ << " "
<< diveded_member_ << " ";
}
private:
class boost::serialization::access;
template<typename Archive>
void serialize_base_class(Archive& ar)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
}
template<typename Archive, typename TT>
friend void serialize(Archive& ar, divided_class<TT>& divcls, const unsigned int file_version);
private:
T diveded_member_;
//other member....
};
template<typename Archive, typename T>
void serialize(Archive& ar, divided_class<T>& discls, const unsigned int file_version)
{
discls.serialize_base_class(ar);
ar & BOOST_SERIALIZATION_NVP(discls.diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
void save()
{
std::ofstream ofs("t8.xml");
boost::archive::xml_oarchive oa(ofs);
base_class* int_base = new divided_class<int>(1, 3);
base_class* str_base = new divided_class<std::string>(1, "wyp");
base_class* float_base = new divided_class<float>(1, 3.1415926f);
//Now the tricky point is to register class in serialize
oa.template register_type<divided_class<int>>(NULL);
oa.template register_type<divided_class<std::string>>(NULL);
oa.template register_type<divided_class<float>>(NULL);
//begin serialize
oa & BOOST_SERIALIZATION_NVP(int_base);
oa & BOOST_SERIALIZATION_NVP(str_base);
oa & BOOST_SERIALIZATION_NVP(float_base);
//delete pointer ...
}
{
public:
base_class(int m=0) : base_member_(0) {}
virtual ~base_class() {} virtual void print_data() = 0; private:
template<typename Archive>
friend void serialize(Archive& ar, base_class& bascls, const unsigned int file_version);
protected:
int base_member_;
//other member...
}; template<typename Archive>
void serialize(Archive& ar, base_class& bascls, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(bascls.base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
} template<typename T>
class divided_class : public base_class
{
public:
divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
virtual ~divided_class() {} virtual void print_data()
{
std::cout << base_member_ << " "
<< diveded_member_ << " ";
} private:
class boost::serialization::access;
template<typename Archive>
void serialize_base_class(Archive& ar)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
} template<typename Archive, typename TT>
friend void serialize(Archive& ar, divided_class<TT>& divcls, const unsigned int file_version); private:
T diveded_member_;
//other member....
}; template<typename Archive, typename T>
void serialize(Archive& ar, divided_class<T>& discls, const unsigned int file_version)
{
discls.serialize_base_class(ar);
ar & BOOST_SERIALIZATION_NVP(discls.diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
} void save()
{
std::ofstream ofs("t8.xml");
boost::archive::xml_oarchive oa(ofs); base_class* int_base = new divided_class<int>(1, 3);
base_class* str_base = new divided_class<std::string>(1, "wyp");
base_class* float_base = new divided_class<float>(1, 3.1415926f); //Now the tricky point is to register class in serialize
oa.template register_type<divided_class<int>>(NULL);
oa.template register_type<divided_class<std::string>>(NULL);
oa.template register_type<divided_class<float>>(NULL); //begin serialize
oa & BOOST_SERIALIZATION_NVP(int_base);
oa & BOOST_SERIALIZATION_NVP(str_base);
oa & BOOST_SERIALIZATION_NVP(float_base); //delete pointer ...
}
错误代码例如以下(有兴趣的调下。。。。error存档):
class base_class
{
public:
base_class(int m=0) : base_member_(0) {}
virtual ~base_class() {}
virtual void print_data() = 0;
private:
class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
protected:
int base_member_;
//other member...
};
template<typename T>
class divided_class : public base_class
{
public:
divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
virtual ~divided_class() {}
virtual void print_data()
{
std::cout << base_member_ << " "
<< diveded_member_ << " ";
}
private:
class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
ar & BOOST_SERIALIZATION_NVP(diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
private:
T diveded_member_;
//other member....
};
void save()
{
std::ofstream ofs("t8.xml");
boost::archive::xml_oarchive oa(ofs);
base_class* int_base = new divided_class<int>(1, 3);
base_class* str_base = new divided_class<std::string>(1, "wyp");
base_class* float_base = new divided_class<float>(1, 3.1415926f);
//Now the tricky point is to register class in serialize
oa.template register_type<divided_class<int>>(NULL);
oa.template register_type<divided_class<std::string>>(NULL);
oa.template register_type<divided_class<float>>(NULL);
//begin serialize
oa & BOOST_SERIALIZATION_NVP(int_base);
oa & BOOST_SERIALIZATION_NVP(str_base);
oa & BOOST_SERIALIZATION_NVP(float_base);
//delete pointer ...
}//求大神解决这个问题。。。。
{
public:
base_class(int m=0) : base_member_(0) {}
virtual ~base_class() {} virtual void print_data() = 0; private:
class boost::serialization::access;
template<typename Archive>
void serialize(Archive & ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_NVP(base_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
} protected:
int base_member_;
//other member...
}; template<typename T>
class divided_class : public base_class
{
public:
divided_class(int m = 0, T d = T()) : base_class(m), diveded_member_(d) {}
virtual ~divided_class() {} virtual void print_data()
{
std::cout << base_member_ << " "
<< diveded_member_ << " ";
} private:
class boost::serialization::access;
template<typename Archive>
void serialize(Archive& ar, const unsigned int file_version)
{
ar & BOOST_SERIALIZATION_BASE_OBJECT_NVP(base_class);
ar & BOOST_SERIALIZATION_NVP(diveded_member_);
//ar & BOOST_SERIALIZATION_NVP(other member...);
}
private:
T diveded_member_;
//other member....
}; void save()
{
std::ofstream ofs("t8.xml");
boost::archive::xml_oarchive oa(ofs); base_class* int_base = new divided_class<int>(1, 3);
base_class* str_base = new divided_class<std::string>(1, "wyp");
base_class* float_base = new divided_class<float>(1, 3.1415926f); //Now the tricky point is to register class in serialize
oa.template register_type<divided_class<int>>(NULL);
oa.template register_type<divided_class<std::string>>(NULL);
oa.template register_type<divided_class<float>>(NULL); //begin serialize
oa & BOOST_SERIALIZATION_NVP(int_base);
oa & BOOST_SERIALIZATION_NVP(str_base);
oa & BOOST_SERIALIZATION_NVP(float_base); //delete pointer ...
}//求大神解决这个问题。。。。
如何用boost::serialization去序列化派生模板类(续)的更多相关文章
- boost::serialization 用基类指针转存派生类(错误多多,一波三折)
boost::serialization 也支持c++的多态,这样我们就能够通过使用基类的指针来转存派生类, 我们接着上一篇( boost::serialization(2)序列化基类 )的样例来看: ...
- 最经常使用的两种C++序列化方案的使用心得(protobuf和boost serialization)
导读 1. 什么是序列化? 2. 为什么要序列化?优点在哪里? 3. C++对象序列化的四种方法 4. 最经常使用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序猿在编写应用程序的时候往往须 ...
- 最常用的两种C++序列化方案的使用心得(protobuf和boost serialization)
导读 1. 什么是序列化? 2. 为什么要序列化?好处在哪里? 3. C++对象序列化的四种方法 4. 最常用的两种序列化方案使用心得 正文 1. 什么是序列化? 程序员在编写应用程序的时候往往需要将 ...
- 【boost】使用serialization库序列化子类
boost.serialization库是一个非常强大又易用的序列化库,用于对象的保存与持久化等. 使用base_object可以在序列化子类的同时也序列化父类,以此获得足够的信息来从文件或网络数据中 ...
- [LeetCode] Serialize and Deserialize BST 二叉搜索树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- [LeetCode] Serialize and Deserialize Binary Tree 二叉树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- [LeetCode] Serialize and Deserialize N-ary Tree N叉搜索树的序列化和去序列化
Serialization is the process of converting a data structure or object into a sequence of bits so tha ...
- 为什么hadoop中用到的序列化不是java的serilaziable接口去序列化而是使用Writable序列化框架
继上一个模块之后,此次分析的内容是来到了Hadoop IO相关的模块了,IO系统的模块可谓是一个比较大的模块,在Hadoop Common中的io,主要包括2个大的子模块构成,1个是以Writable ...
- boost serialization
Archive An archive is a sequence of bytes that represented serialized C++ objects. Objects can be ad ...
随机推荐
- 在Windows下编译FFmpeg详细说明
MinGW:一个可自由使用和自由发布的Windows特定头文件和使用GNC工具集导入库的集合,允许你生成本地的Windows程序而不需要第三方C运行时 MinGW,即 Minimalist GNU F ...
- UVa 11300 Spreading the Wealth 分金币
圆桌旁坐着 n 个人,每个人都有一定数量的金币,金币总数能够被 n 整除.每个人可以给他左右相邻的人一些金币,最终使得每个人的金币数目相等.你的任务是求出被转手的金币数量的最小值,比如 n = 4, ...
- ORACLE CLIENT客户端安装步骤详解
下载地址: http://download.oracle.com/otn/nt/oracle11g/112010/win32_11gR2_client.zip 先将下载下来的ZIP文件解压,并运行se ...
- Linux 中直接 I/O 机制的介绍
https://www.ibm.com/developerworks/cn/linux/l-cn-directio/ 对于传统的操作系统来说,普通的 I/O 操作一般会被内核缓存,这种 I/O 被称作 ...
- 1050 数的计数 c语言实现
描述 给定一个正整数,求其各位之和. 输入 输入一行,为一个正整数(最多10,000位). 输出 输出各位之和. 样例输入 17 样例输出 8 解析:这题主要是大数计算的问题,因为10000位的数无法 ...
- 动画 -- ListView列表item逐个出来(从无到有)
import android.app.ListActivity; import android.os.Bundle; import android.widget.ArrayAdapter; publi ...
- C#控制定位Word光标移动到任意行或者最后一行,取得光标位置等操作
C#控制定位Word光标移动到任意行或者最后一行,取得光标位置等操作 http://blog.csdn.net/jglie/article/details/7394256 十一.上下左右移动光标位 p ...
- C# 替换文本文件中的某一行
C# 替换文本文件中的某一行 (要求此文件存在) /// <summary> /// LineIndex 表示新的内容所在的行位置 /// </summary> /// < ...
- Mondriaan's Dream(POJ 2411状态压缩dp)
题意:用1*2的方格填充m*n的方格不能重叠,问有多少种填充方法 分析:dp[i][j]表示i行状态为j时的方案数,对于j,0表示该列竖放(影响下一行的该列),1表示横放成功(影响下一列)或上一列竖放 ...
- codeforces 696A Lorenzo Von Matterhorn 水题
这题一眼看就是水题,map随便计 然后我之所以发这个题解,是因为我用了log2()这个函数判断在哪一层 我只能说我真是太傻逼了,这个函数以前听人说有精度问题,还慢,为了图快用的,没想到被坑惨了,以后尽 ...