在《使用 acl 库针对 C++ 对象进行序列化及反序列编程》中介绍了 acl 库中针对 C/C++ 的 struct 对象进行序列化和反序列化的功能,并且给出了一个简单的例子。本文将介绍一些较为复杂的例子。
一、示例一:支持多继承的例子
先定义 struct.stub 文件:
#pragma once #include <string> struct student { std::string shcool; std::string class_name; }; struct province { std::string province_name; std::string position; }; struct user : student, province { std::string name; int age; bool male; };
上面的定义中,user 继承于 student 和 province。
然后使用 gson 工具(运行:./gson -d )根据此 struct.stub 生成目标源文件和头文件:gson.cpp, gson.h, struct.h。
下面就可以编写业务逻辑代码:
#include "stdafx.h" #include <list> #include <vector> #include <map> #include <stdio.h> #include <iostream> #include <time.h> #include "struct.h" // 由 gson 工具根据 struct.stub 转换而成 #include "gson.h" // 由 gson 工具根据 struct.stub 生成 // 序列化过程 static void serialize(void) { user u; u.name = "zsx"; u.age = 11; u.male = true; u.province_name = "省"; u.position = "位置"; u.shcool = "大学"; u.class_name = "班级"; acl::json json; // 将 user 对象转换为 json 对象 acl::json_node& node = acl::gson(json, u); printf("serialize:\r\n"); printf("json: %s\r\n", node.to_string().c_str()); printf("\r\n"); } // 反序列化过程 static void deserialize(void) { const char *s = "{\"shcool\": \"大学\", \"class_name\": \"班级\", \"province_name\": \"省\", \"position\": \"位置\", \"name\": \"zsx\", \"age\": 11, \"male\": true}"; printf("deserialize:\r\n"); acl::json json; json.update(s); user u; // 将 json 对象转换为 user 对象 std::pair<bool, std::string> ret = acl::gson(json.get_root(), u); // 如果转换失败,则打印转换失败原因 if (ret.first == false) printf("error: %s\r\n", ret.second.c_str()); else { printf("name: %s, age: %d, male: %s\r\n", u.name.c_str(), u.age, u.male ? "yes" : "no"); printf("province_name: %s, position: %s\r\n", u.province_name.c_str(), u.position.c_str()); printf("shcool: %s, class_name: %s\r\n", u.shcool.c_str(), u.class_name.c_str()); } } int main(void) { serialize(); deserialize(); return 0; }
编译并运行该例子,结果如下:
serialize: json: {"shcool": "大学", "class_name": "班级", "province_name": "省", "position": "位置", "name": "zsx", "age": 11, "male": true} deserialize: name: zsx, age: 11, male: yes province_name: 省, position: 位置 shcool: 大学, class_name: 班级
二、示例二:支持 C++11 的例子
定义 struct.stub 文件如下:
#pragma once struct user { // 带参数的构造函数 user(const char* user_name, const char* user_domain, int user_age, bool user_male) : username(user_name) , domain(user_domain) , age(user_age) , male(user_male) {} user() {} ~user() {} acl::string username; acl::string domain; int age = 100; bool male = true; }; struct message { int type; acl::string cmd; std::list<user> user_list; std::list<user> user_vector; std::map<acl::string, user> user_map; std::list<user*> *user_list_ptr = nullptr; std::vector<user*> *user_vector_ptr = nullptr; std::map<acl::string, user*> *user_map_ptr = nullptr; int n = 100; // c++11 允许初始化成员变量 long n1 = 1000; long long int n2 = 1000; short n3 = 100; //Gson@optional user* u = nullptr; message() {} ~message() { if (user_list_ptr) { for (auto it : *user_list_ptr) delete it; delete user_list_ptr; } if (user_vector_ptr) { for (auto it : *user_vector_ptr) delete it; delete user_vector_ptr; } if (user_map_ptr) { for (auto it : *user_map_ptr) delete it.second; delete user_map_ptr; } } };
用 gson 工具将上述 stub 文件生成同样的三个文件:gson.cpp, gson.h, struct.h,然后编写业务处理代码如下:
#include "stdafx.h" #include <list> #include <vector> #include <map> #include <stdio.h> #include <iostream> #include <time.h> #include "struct.h" #include "gson.h" static void print_msg(message& msg) { printf("=======================================================\r\n"); printf("type: %d\r\n", msg.type); printf("cmd: %s\r\n", msg.cmd.c_str()); printf("-------------------- user list ------------------------\r\n"); size_t i = 0; for (auto cit : msg.user_list) { printf(">>username: %s, domain: %s, age: %d, male: %s\r\n", cit.username.c_str(), cit.domain.c_str(), cit.age, cit.male ? "true" : "false"); if (++i >= 10) break; } printf("-------------------- user vector ----------------------\r\n"); i = 0; for (auto cit : msg.user_vector) { printf(">>username: %s, domain: %s, age: %d, male: %s\r\n", cit.username.c_str(), cit.domain.c_str(), cit.age, cit.male ? "true" : "false"); if (++i >= 10) break; } printf("------------------- user map --------------------------\r\n"); i = 0; for (auto cit : msg.user_map) { printf(">>key: %s, username: %s, domain: %s, age: %d, male: %s\r\n", cit.first.c_str(), cit.second.username.c_str(), cit.second.domain.c_str(), cit.second.age, cit.second.male ? "true" : "false"); if (++i >= 10) break; } printf("-------------------- user list ptr --------------------\r\n"); i = 0; for (auto cit : *msg.user_list_ptr) { printf(">>username: %s, domain: %s, age: %d, male: %s\r\n", cit->username.c_str(), cit->domain.c_str(), cit->age, cit->male ? "true" : "false"); if (++i >= 10) break; } printf("-------------------- user vector ptr ------------------\r\n"); i = 0; for (auto cit : *msg.user_vector_ptr) { printf(">>username: %s, domain: %s, age: %d, male: %s\r\n", cit->username.c_str(), cit->domain.c_str(), cit->age, cit->male ? "true" : "false"); if (++i >= 10) break; } printf("------------------- user map ptr ----------------------\r\n"); i = 0; for (auto cit : *msg.user_map_ptr) { printf(">>key: %s, username: %s, domain: %s, age: %d, male: %s\r\n", cit.first.c_str(), cit.second->username.c_str(), cit.second->domain.c_str(), cit.second->age, cit.second->male ? "true" : "false"); if (++i >= 10) break; } printf("-------------------------------------------------------\r\n"); } static void test(void) { ////////////////////////////////////////////////////////////////// // 序列化过程 message msg; msg.user_list_ptr = new std::list<user*>; msg.user_vector_ptr = new std::vector<user*>; msg.user_map_ptr = new std::map<acl::string, user*>; msg.type = 1; msg.cmd = "add"; user u = {"zsx1", "263.net", 11, true}; msg.user_list.push_back(u); msg.user_list.emplace_back(u); msg.user_list.emplace_back("zsx1", "263.net", 13, false); u = {"zsx2", "263.net", 11, true}; msg.user_vector.push_back(u); msg.user_vector.emplace_back(u); msg.user_vector.emplace_back("zsx2", "263.net4", 14, true); u = {"zsx31", "263.net", 11, true}; msg.user_map[u.username] = u; msg.user_map["zsx32"] = {"zsx32", "263.net", 11, true }; msg.user_list_ptr->push_back(new user("zsx4", "263.net1", 11, true)); msg.user_list_ptr->push_back(new user("zsx4", "263.net2", 12, true)); msg.user_vector_ptr->push_back(new user("zsx5", "263.net1", 11, true)); msg.user_vector_ptr->push_back(new user("zsx5", "263.net2", 12, true)); (*msg.user_map_ptr)["zsx61"] = new user("zsx61:", "263.net1", 11, true); (*msg.user_map_ptr)["zsx62"] = new user("zsx62", "263.net2", 12, true); acl::json json; // 序列化 acl::json_node& node = acl::gson(json, msg); printf("serialize: %s\r\n", node.to_string().c_str()); ///////////////////////////////////////////////////////////////////// // 反序列化过程 message msg1; acl::json json1; json1.update(node.to_string()); printf("json1 to_string: %s\r\n", json1.to_string().c_str()); // 反序列化 std::pair<bool, std::string> ret = acl::gson(json1.get_root(), msg1); if (ret.first == false) printf("error: %s\r\n", ret.second.c_str()); else print_msg(msg); } int main(void) { test(); return 0; }
上述例子主要体现了 gson 的两个特点:1、允许有构造函数,2、支持 C++11 中的结构成员初始化。
三、参考
文章参考:《使用 acl 库针对 C++ 对象进行序列化及反序列编程》
更多示例:https://github.com/acl-dev/acl/tree/master/app/gson/test
acl github:https://github.com/acl-dev/acl
acl download: https://sourceforge.net/projects/acl/
QQ 群:242722074
相关推荐
在C++中,为了将C++对象转换为JSON格式的字符串,或者将JSON字符串解析为C++对象,我们需要使用JSON序列化库。这篇内容我们将深入探讨C++中的JSON序列化,基于提供的资源,我们可以推测这是一个关于如何在C++中实现...
3. 序列化:在程序中,实例化消息对象并填充数据,然后调用相关方法将其转换为字节流。 4. 反序列化:接收字节流后,通过protobuf提供的API解析字节流并恢复为对象。 在实时大数据处理中,protobuf的高效特性使其...
在编程领域,序列化和反序列化是两个关键的概念,它们用于将对象的状态转换为可存储或可传输的格式,然后在需要时恢复为原始对象。Boost库提供了一个强大的工具——Boost.Serialization,来帮助程序员实现这个功能。...
MFC提供了CFile类来处理文件读写,CArchive类则支持序列化,方便地保存和加载对象的状态。 MFC数据库编程通过ODBC(Open Database Connectivity)接口,使开发者可以访问各种数据库。CDatabase和CRecordset类简化了...
**Visual C++ MFC编程实例** MFC(Microsoft Foundation Classes)是微软开发的一个类库,它基于C++,为Windows应用程序开发提供了一种强大的框架。MFC将Windows API封装成了一系列易于使用的C++类,使得开发者可以...
C++是一种静态类型的、编译式的、通用的、大小写敏感的、不仅支持过程化编程,也支持面向对象编程的程序设计语言。它的强大之处在于提供了模板和STL(Standard Template Library,标准模板库),使得代码可重用性更...
`SerializeToString`方法将消息对象序列化成字符串`message`。 ### 2. 反序列化 反序列化则是将二进制流恢复为结构化数据的过程。protobuf提供了相应的API来完成这一操作: ```cpp // C++ 示例 MyMessage my_...
《Visual C++编程实例100篇》是一个深入学习和实践C++编程的宝贵资源,它涵盖了广泛的编程主题,旨在帮助开发者提升技能并解决实际问题。这个压缩包中包含了一系列的源代码,提供了丰富的示例,是学习和理解C++语言...
`CArchive`类尤其有用,它允许以序列化的方式保存和加载对象状态,从而实现持久化存储。 网络编程方面,MFC包含了`CSocket`类,用于实现TCP/IP通信。通过创建和连接套接字,开发者可以构建客户端-服务器应用程序。 ...
《Visual C++ MFC编程实例》是一本专为初学者设计的教程,旨在帮助读者快速掌握Microsoft Foundation Classes (MFC)库的使用,以便在Visual C++环境下进行高效的应用程序开发。MFC是微软公司提供的一个C++类库,它...
每个章节的命名(如第十章、第六章等)可能代表不同的主题或技术,如网络套接字编程、数据序列化、错误处理等。 6. **章节结构**: 从压缩包的文件名来看,这个实例可能按照章节组织,从基础知识到高级主题逐步...
2. 基础类:如CObject,它是所有MFC类的基类,提供了对象序列化、动态类型识别等特性。 3. 视图类:如CView,是显示数据和接收用户输入的类。常见的视图类有CScrollView(支持滚动)、CListView(列表视图)和...
本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...
对象序列化是编程领域中的一个重要概念,特别是在Java中,它允许我们将对象的状态转换为字节流,以便可以存储或在网络上传输。这个过程是通过实现Java的`Serializable`接口来完成的,使得对象的数据能够被持久化。在...
C++标准库提供了fstream库来读写文件,可以编写函数将员工信息序列化到文件,或者从文件反序列化。 9. **异常处理**: - 在处理用户输入或系统错误时,应加入异常处理机制,以防止程序因意外情况崩溃。 10. **...
综上所述,"VC序列化-存储文件方法"是一个关键的编程技巧,它使得C++程序员能够有效地管理对象的状态,实现数据的持久化存储和恢复。通过理解和掌握这一技术,开发者可以构建更强大、更灵活的应用程序。
《Visual C++ MFC扩展编程实例》是一本深入探讨C++和MFC(Microsoft Foundation Classes)框架的应用开发书籍。MFC是由微软公司推出的C++类库,它为Windows应用程序开发提供了一种高效、便捷的方式。这本书针对那些...
9. **文件操作**:使用MFC的文件I/O功能读写文件,如序列化和反序列化对象。 10. **异常处理**:学习MFC的异常处理机制,以及如何在代码中有效地捕获和处理错误。 11. **网络编程**:通过MFC的网络类,实现基本的...