在《使用 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
相关推荐
本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...
本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...
1.11.2 CArchive和序列化 16 1.11.3 数据库类 17 1.11.4 ODBC类 17 1.11.5 DAO类 17 1.11.6 数据集合类 17 1.11.7 通信类 18 1.12 类的消息机制 18 1.12.1 MFC如何接收一个寄送消息 18 1.12.2 MFC如何处理接收的消息...
Visual c++ MFC扩展编程实例及源代码,非常经典的学习教材 本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程...
《现代C++程序设计(原书第2版)》图文并茂,通俗易懂,真正做到寓教于乐,是一本难得的C++面向对象设计入门教材。 出版者的话 译者序 前言 第1章 C++概述与软件开发 1.1 什么是C语言和C++ 1.1.1 C和C++历史回顾 1.1.2...
深度解析C++准标准库(第2版)》基于Boost 1.54版,深入探讨了其中的许多重要组件,包括迭代器、函数对象、容器、流处理、序列化以及C++语言中最复杂最具威力的模板元编程,并专辟一章详细阐述Boost的开发实例,具有...
本书采用生动轻松的语言,深入阐述了C++语言和面向对象程序设计技术。书中设计了超过115个完整的经过教学测试的代码示例,不仅分析了这些示例的代码片段,而且还解释了如何把它们组成一个完整的程序。此外,各章后面...
7.2 数据类型、对象、类和实例 301 7.2.1 类的起源 303 7.2.2 类的操作 303 7.2.3 术语 303 7.3 理解类 304 7.3.1 定义类 304 7.3.2 声明类的对象 305 7.3.3 访问类的数据成员 305 7.3.4 类的成员函数 307 ...
7.2 数据类型、对象、类和实例 7.2.1 类的起源 7.2.2 类的操作 7.2.3 术语 7.3 理解类 7.3.1 定义类 7.3.2 声明类的对象 7.3.3 访问类的数据成员 7.3.4 类的成员函数 7.3.5 成员函数定义的位置 7.3.6 内联函数 7.4 ...
7.2 数据类型、对象、类和实例 7.2.1 类的起源 7.2.2 类的操作 7.2.3 术语 7.3 理解类 7.3.1 定义类 7.3.2 声明类的对象 7.3.3 访问类的数据成员 7.3.4 类的成员函数 7.3.5 成员函数定义的位置 7.3.6 内联函数 7.4 ...
全书共12章,主要包括:Java 2编程基础、面向对象编程原理、接口、包、字符串类String和StringBuffer、异常处理、输入和输出、多线程、Java小程序、GUI布局管理、对象序列化、内隐类、Adapter类和事件处理等,非常...
在Windows中有各种GUI对象(不要和C++对象混淆),当你在进行绘图就需要利用这些对象。而各种对象都拥有各种属性,下面分别讲述各种GUI对象和拥有的属性。 字体对象CFont用于输出文字时选用不同风格和大小的字体。可...
7.2 数据类型、对象、类和实例 7.2.1 类的起源 7.2.2 类的操作 7.2.3 术语 7.3 理解类 7.3.1 定义类 7.3.2 声明类的对象 7.3.3 访问类的数据成员 7.3.4 类的成员函数 7.3.5 成员函数定义的位置 7.3.6 内联函数 7.4 ...
主要包括Java编程基础知识、Java算术运算符、Java编程语法、面向对象程序设计基本概念、系统类的使用和应用、图形用户界面设计、图形处理、多媒体处理、异常处理、多线程、网络编程、输入输出处理与序列化、Java本机...
16.1.5 控制实例化 597 16.1.6 效率与灵活性 599 16.2 模板实参推断 600 16.2.1 类型转换与模板类型参数 601 16.2.2 函数模板显式实参 603 16.2.3 尾置返回类型与类型转换 604 16.2.4 函数指针和实参...
16.1.5 控制实例化 597 16.1.6 效率与灵活性 599 16.2 模板实参推断 600 16.2.1 类型转换与模板类型参数 601 16.2.2 函数模板显式实参 603 16.2.3 尾置返回类型与类型转换 604 16.2.4 函数指针和实参...
7.2 数据类型、对象、类和实例 303 7.2.1 类的起源 305 7.2.2 类的操作 305 7.2.3 术语 306 7.3 理解类 306 7.3.1 定义类 307 7.3.2 声明类的对象 307 7.3.3 访问类的数据成员 308 7.3.4 类的成员...
7.2 数据类型、对象、类和实例 7.2.1 类的起源 7.2.2 类的操作 7.2.3 术语 7.3 理解类 7.3.1 定义类 7.3.2 声明类的对象 7.3.3 访问类的数据成员 7.3.4 类的成员函数 7.3.5 成员函数定义的位置 7.3.6 内联函数 7.4 ...