C++ object serialization programming example

      In "Using the acl library to serialize and deserialize programming for C++ objects" , the function of serializing and deserializing C/C++ struct objects in the acl library is introduced, and a simple example is given. This article will introduce some more complex examples.

      1. Example 1: Example of Supporting Multiple Inheritance

      First define the struct.stub file:

#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;
};

      In the above definition, user inherits from student and province.

      Then use the gson tool (run: ./gson -d ) to generate the target source and header files from this struct.stub: gson.cpp, gson.h, struct.h.

      The business logic code can be written as follows:

#include "stdafx.h"
#include <list>
#include <vector>
#include <map>
#include <stdio.h>
#include <iostream>
#include <time.h>
#include "struct.h" // Converted from struct.stub by gson tool
#include "gson.h" // Generated by gson tool based on struct.stub

// serialization process
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;

	// Convert user object to json object
	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");
}

// deserialization process
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;

	// Convert json object to user object
	std::pair<bool, std::string> ret = acl::gson(json.get_root(), u);

	// If the conversion fails, print the reason for the conversion failure
	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;
}

       Compile and run the example, the results are as follows:

serialize:
json: {"shcool": "大学", "class_name": "班级", "province_name": "省", "position": "位置", "name": "zsx", "age": 11, "male": true}

deserialize:
name: zsx, age: 11, male: yes
province_name: province, position: position
shcool: university, class_name: class

 

      2. Example 2: An example of supporting C++11

      Define the struct.stub file as follows:

#pragma once

struct user
{
	// constructor with parameters
	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 allows initialization of member variables
	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;
		}
	}
};

       Use the gson tool to generate the same three files from the above stub file: gson.cpp, gson.h, struct.h, and then write the business processing code as follows:

#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)
{
	//////////////////////////////////////////////////////////////////
	// serialization process

	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;

	// Serialization
	acl::json_node& node = acl::gson(json, msg);
	printf("serialize: %s\r\n", node.to_string().c_str());

	/////////////////////////////////////////////////////////////////////
	// deserialization process

	message msg1;
	acl::json json1;
	json1.update(node.to_string());

	printf("json1 to_string: %s\r\n", json1.to_string().c_str());

	// deserialize
	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;
}

       The above example mainly embodies two characteristics of gson: 1. It allows constructors, 2. It supports the initialization of structure members in C++11.

 

      3. Reference

      Article reference: " Using the acl library for serialization and deserialization of C++ objects "

      More examples: 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 group: 242722074

 

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326933888&siteId=291194637