C++ 序列化和反序列化是将对象的状态信息转换为可以存储或传输的格式的过程,以及从这种格式恢复对象状态的过程
- 序列化:
序列化是将对象的状态信息转换为字节流或其他可存储或传输的格式的过程。这通常涉及到访问对象的私有成员变量,并将它们转换为一种通用的数据表示形式,如二进制、XML、JSON等。
实现原理:
- 使用输出流(如 ostream)将对象的成员变量逐个写入字节流。
- 对于复杂的数据结构,可以使用递归方法遍历对象的所有成员变量,并将它们写入字节流。
- 在序列化过程中,可能需要处理不同类型的数据,例如基本数据类型、字符串、容器等。为了实现通用性,可以使用模板函数或者运行时类型信息(RTTI)来处理不同类型的数据。
- 反序列化:
反序列化是从字节流或其他可存储或传输的格式中恢复对象状态的过程。这通常涉及到创建一个新的对象,并将字节流中的数据设置为对象的成员变量。
实现原理:
- 使用输入流(如 istream)从字节流中读取数据,并将其设置为对象的成员变量。
- 对于复杂的数据结构,可以使用递归方法遍历对象的所有成员变量,并从字节流中读取相应的数据。
- 在反序列化过程中,可能需要处理不同类型的数据,例如基本数据类型、字符串、容器等。为了实现通用性,可以使用模板函数或者运行时类型信息(RTTI)来处理不同类型的数据。
- 示例代码:
#include
#include
#include
class Person {
public:
std::string name;
int age;
// 序列化函数
void serialize(std::ostream& os) const {
os.write(reinterpret_cast(&age), sizeof(age));
std::string nameSize = std::to_string(name.size());
os.write(nameSize.c_str(), nameSize.size());
os.put('\0'); // 添加空字符作为字符串长度的终止符
os.write(name.c_str(), name.size());
}
// 反序列化函数
void deserialize(std::istream& is) {
is.read(reinterpret_cast(&age), sizeof(age));
std::string nameSize;
char ch;
while (is.get(ch) && ch != '\0') {
nameSize += ch;
}
name.resize(std::stoi(nameSize));
is.read(&name[0], name.size());
}
};
int main() {
// 创建一个 Person 对象并序列化到文件
Person person1;
person1.name = "Alice";
person1.age = 30;
std::ofstream outFile("person.bin", std::ios::binary);
person1.serialize(outFile);
outFile.close();
// 从文件反序列化 Person 对象
Person person2;
std::ifstream inFile("person.bin", std::ios::binary);
person2.deserialize(inFile);
inFile.close();
// 输出反序列化后的 Person 对象
std::cout << "Name: "<< person2.name << ", Age: "<< person2.age<< std::endl;
return 0;
}
注意:这个示例仅用于演示基本的序列化和反序列化原理,实际应用中可能需要处理更复杂的数据结构和错误处理。在实际项目中,可以考虑使用成熟的序列化库,如 Boost.Serialization、Protocol Buffers 等。