周口网站设计制作,自己可以学做网站吗,做网站用什么云服务器,群晖网站建设一、C 中的序列化和反序列化
#xff08;一#xff09;基本概念
在 C 中#xff0c;序列化是将对象转换为字节流的过程#xff0c;反序列化则是从字节流重新构建对象的过程。这对于存储对象状态到文件、网络传输等场景非常有用。
#xff08;二#xff09;简单的序列化…一、C 中的序列化和反序列化
一基本概念
在 C 中序列化是将对象转换为字节流的过程反序列化则是从字节流重新构建对象的过程。这对于存储对象状态到文件、网络传输等场景非常有用。
二简单的序列化和反序列化实现方式
1. 基于文本格式
序列化 一种简单的方法是将对象的成员变量以特定的格式如 CSV - 逗号分隔值写入文件。例如假设有一个Person类包含姓名和年龄两个成员变量。#include iostream #include fstream #include stringclass Person { public: std::string name; int age; Person(const std::string n, int a) : name(n), age(a) {} };void serializeToText(const Person p, const std::string filename) { std::ofstream file(filename); if (file.is_open()) { file p.name , p.age std::endl; file.close(); } else { std::cerr 无法打开文件进行序列化。 std::endl; } }反序列化Person deserializeFromText(const std::string filename) { std::ifstream file(filename); Person p(, 0); if (file.is_open()) { std::string line; if (std::getline(file, line)) { size_t pos line.find(,); if (pos! std::string::npos) { p.name line.substr(0, pos); p.age std::stoi(line.substr(pos 1)); } } file.close(); } else { std::cerr 无法打开文件进行反序列化。 std::endl; } return p; }
2. 使用二进制格式更高效但不可读
序列化 使用fstream库的二进制模式来写入对象的内存表示。不过需要注意字节序等问题。void serializeToBinary(const Person p, const std::string filename) { std::ofstream file(filename, std::ios::binary); if (file.is_open()) { // 先写入姓名长度 int nameLength p.name.length(); file.write(reinterpret_castconst char*(nameLength), sizeof(int)); // 再写入姓名内容 file.write(p.name.c_str(), nameLength); // 写入年龄 file.write(reinterpret_castconst char*(p.age), sizeof(int)); file.close(); } else { std::cerr 无法打开文件进行二进制序列化。 std::endl; } }反序列化Person deserializeFromBinary(const std::string filename) { std::ifstream file(filename, std::ios::binary); Person p(, 0); if (file.is_open()) { // 先读取姓名长度 int nameLength; file.read(reinterpret_castchar*(nameLength), sizeof(int)); char* buffer new char[nameLength 1]; // 读取姓名内容 file.read(buffer, nameLength); buffer[nameLength] \0; p.name buffer; delete[] buffer; // 读取年龄 file.read(reinterpret_castchar*(p.age), sizeof(int)); file.close(); } else { std::cerr 无法打开文件进行二进制反序列化。 std::endl; } return p; }
三使用第三方库如 Boost.Serialization进行序列化和反序列化
安装和配置 Boost 库 首先需要下载并安装 Boost 库这通常涉及从 Boost 官方网站获取源代码然后通过编译安装到系统中。安装过程因操作系统而异。使用示例 以下是使用 Boost.Serialization 对Person类进行序列化和反序列化的简单示例。#include iostream #include fstream #include boost/archive/text_oarchive.hpp #include boost/archive/text_iarchive.hpp #include boost/serialization/string.hppclass Person { public: std::string name; int age; Person(const std::string n, int a) : name(n), age(a) {} // 为了让Boost.Serialization能够访问私有成员需要添加这两个友元函数 friend class boost::serialization::access; templateclass Archive void serialize(Archive ar, const unsigned int version) { ar name; ar age; } };void serializeWithBoost(const Person p, const std::string filename) { std::ofstream file(filename); if (file.is_open()) { boost::archive::text_oarchive oa(file); oa p; file.close(); } else { std::cerr 无法打开文件进行Boost序列化。 std::endl; } }Person deserializeWithBoost(const std::string filename) { std::ifstream file(filename); Person p(, 0); if (file.is_open()) { boost::archive::text_iarchive ia(file); ia p; file.close(); } else { std::cerr 无法打开文件进行Boost反序列化。 std::endl; } return p; }
二、C 中的对象生命周期管理
一对象生命周期阶段
创建 栈对象在函数内部定义的对象当程序执行到对象定义处时会调用对象的构造函数进行创建。例如Person p(Alice, 30);这里p是一个栈对象它的生命周期从定义处开始到所在的代码块结束如函数返回。堆对象通过new关键字在堆上分配内存创建对象。例如Person* p new Person(Bob, 25);此时需要手动管理内存使用delete来释放内存。使用在对象的生命周期内可以通过对象的成员函数访问和修改对象的状态就像p-getName()或p.setName(Charlie);这样的操作。销毁 栈对象当栈对象所在的代码块结束时对象的析构函数会被自动调用用于清理对象占用的资源。堆对象需要手动调用delete来释放堆上对象占用的内存并且在调用delete后对象的析构函数会被调用。如果忘记调用delete就会导致内存泄漏。
二内存管理和资源清理
RAIIResource Acquisition Is Initialization 这是 C 中一种重要的资源管理机制。核心思想是将资源的获取和初始化放在构造函数中将资源的释放放在析构函数中。例如使用std::unique_ptr或std::shared_ptr来管理动态分配的内存。// 不需要手动释放内存当p离开作用域时Person对象会被自动销毁std::shared_ptr是共享所有权的智能指针用于多个对象共享同一个资源的情况。例如多个对象可能需要共享对同一个数据库连接对象的引用。 手动内存管理使用new和delete当使用new在堆上分配内存时必须在适当的时候使用delete来释放内存。错误地使用delete如多次删除同一个对象或者使用已经删除的对象会导致程序出错如段错误等。并且如果在delete之后还尝试访问对象成员也是未定义行为。