`
zsxxsz
  • 浏览: 444442 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

c++对象序列化编程实例

阅读更多

      在《使用 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

 

0
0
分享到:
评论

相关推荐

    Visual C++ MFC扩展编程实例.PDF

    本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...

    VISUAL C++MFC扩展编程实例

    本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程知识、技巧和方法。全书分为三个部分和附录。第一部分介绍...

    VISUAL C++MFC扩展编程实例(想学MFC的朋友一定不要错过)

    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++ MFC扩展编程实例及源代码,非常经典的学习教材 本书主要介绍了运用Visual C++ 5.0或6.0的高级编程技巧,内容涉及MFC程序设计的最新概念,全书提供了大量VC的编程实例,旨在帮助读者较为全面地掌握VC编程...

    现代C++程序设计

    《现代C++程序设计(原书第2版)》图文并茂,通俗易懂,真正做到寓教于乐,是一本难得的C++面向对象设计入门教材。 出版者的话 译者序 前言 第1章 C++概述与软件开发 1.1 什么是C语言和C++ 1.1.1 C和C++历史回顾 1.1.2...

    Boost程序库探秘 深度解析C++准标准库第2版

    深度解析C++准标准库(第2版)》基于Boost 1.54版,深入探讨了其中的许多重要组件,包括迭代器、函数对象、容器、流处理、序列化以及C++语言中最复杂最具威力的模板元编程,并专辟一章详细阐述Boost的开发实例,具有...

    【全新正版】现代C++程序设计(原书第2版)

    本书采用生动轻松的语言,深入阐述了C++语言和面向对象程序设计技术。书中设计了超过115个完整的经过教学测试的代码示例,不仅分析了这些示例的代码片段,而且还解释了如何把它们组成一个完整的程序。此外,各章后面...

    Visual C++ 2010入门经典(第5版)--源代码及课后练习答案

    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 ...

    Visual C++ 2005入门经典.part08.rar (整理并添加所有书签)

    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 ...

    Visual C++ 2005入门经典.part04.rar (整理并添加所有书签)

    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 ...

    Java2简明教程

    全书共12章,主要包括:Java 2编程基础、面向对象编程原理、接口、包、字符串类String和StringBuffer、异常处理、输入和输出、多线程、Java小程序、GUI布局管理、对象序列化、内隐类、Adapter类和事件处理等,非常...

    C++MFC教程

    在Windows中有各种GUI对象(不要和C++对象混淆),当你在进行绘图就需要利用这些对象。而各种对象都拥有各种属性,下面分别讲述各种GUI对象和拥有的属性。 字体对象CFont用于输出文字时选用不同风格和大小的字体。可...

    Visual C++ 2005入门经典.part05.rar (整理并添加所有书签)

    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 ...

    vc++6.0 程序设计学与用教程

    主要包括Java编程基础知识、Java算术运算符、Java编程语法、面向对象程序设计基本概念、系统类的使用和应用、图形用户界面设计、图形处理、多媒体处理、异常处理、多线程、网络编程、输入输出处理与序列化、Java本机...

    C++ Primer中文版(第5版)李普曼 等著 pdf 1/3

     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 函数指针和实参...

    C++Primer(第5版 )中文版(美)李普曼等著.part2.rar

     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 函数指针和实参...

    Visual C++ 2005入门经典--源代码及课后练习答案

    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 类的成员...

    Visual C++ 2005入门经典.part07.rar (整理并添加所有书签)

    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 ...

Global site tag (gtag.js) - Google Analytics