博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
构建简单的C++运行时反射类型系统
阅读量:6320 次
发布时间:2019-06-22

本文共 3554 字,大约阅读时间需要 11 分钟。

hot3.png

这篇文章中,我构建了一套简单的运行期C++类型系统,当时提到了它的应用场景有字符串映射到类型,本篇文章展示的是它的简单实现。

Metadata.h

#ifndef METADATA_H#define METADATA_H#include 
#include 
#include 
using namespace std;/* * 成员变量的元数据 */struct FieldMetadata{ // 成员变量的名称 string name; // 成员变量的类型 string type; // 成员变量的地址 size_t offset; FieldMetadata(string name, string type, size_t offset) { this->name = name; this->type = type; this->offset = offset; }};/* * 声明结构体类型 */#define Declare_Struct(class_type) \private: \ \typedef class_type this_class; \ \template
 class Init_I \{ \public: \ Init_I(vector
& metas) \ {} \}; \/* * 定义结构体变量 */#define Define_Field(var_index, var_type, var_name) \public: \ \var_type var_name; \ \private: \ \template<> class Init_I
 \{ \public: \ Init_I(vector
& metas) \ { \ FieldMetadata fmd(#var_name, typeid(var_type).name(), offsetof(this_class, var_name)); \ metas.insert(metas.begin(), fmd); \ } \}; \/* * 定义结构体元数据 */#define Define_Metadata(var_count) \public: \ \static vector
 fieldinfo; \ \private: \ \template
 class CallInits \{ \public: \ CallInits(vector
& metas) \ { \ Init_I
 in(metas); \ CallInits
 ci(metas); \ } \}; \ \template<> class CallInits<1> \{ \public: \ CallInits(vector
& metas) \ { \ Init_I<1> in(metas); \ } \}; \ \static vector
 Init() \{ \ vector
 fmd; \ CallInits
 ci(fmd); \ return fmd; \} \/* * 实现结构体类型 */#define Implement_Struct(class_type) \vector
 class_type::fieldinfo = class_type::Init(); \typedef unsigned char byte;/* * 解析字符串到类型 */template
class ParaseToType{private: /*  * 内存值拷贝  */ void CopyValueOnMemory(byte* memvalue, string type, string strvalue) { int off = strvalue.find('='); string name = strvalue.substr(0, off); string value = strvalue.substr(off + 1); if (type.compare(typeid(int).name()) == 0) { int vl = atoi(value.c_str()); memcpy(memvalue, &vl, sizeof(int)); } else if (type.compare(typeid(double).name()) == 0) { double vl = atof(value.c_str()); memcpy(memvalue, &vl, sizeof(double)); }  else if (type.compare(typeid(string).name()) == 0) { string* strmem = (string*)memvalue; strmem->append(value); } else { /*  * Only support the following types  * int, double, std::string  */ assert(false); } }public: /*  * 字符串的格式:"a=5;b=6.0f;c=766666666hhhhhgfdd"  */ bool Parase(_T& t, string strvalue) { int stroffset = 0; for (auto iter = _T::fieldinfo.begin(); iter != _T::fieldinfo.end(); iter++) { int newoffset = strvalue.find(';', stroffset); string ty = strvalue.substr(stroffset, newoffset - stroffset); byte* th = (((byte*)&t) + (*iter).offset); CopyValueOnMemory(th, (*iter).type, ty); stroffset = newoffset + 1; } return true; }};#endif /*METADATA_H*/

Test.h

#pragma once#include "Metadata.h"struct Test{	Declare_Struct(Test)	Define_Field(1, int, a)	Define_Field(2, double, b)	Define_Field(3, string, c)	Define_Metadata(3)};

Test.cpp

#include "Test.h"Implement_Struct(Test)

main.cpp

#include "Test.h"#include 
template
 void PrintFieldInfo(){ printf("struct size : %d \n", sizeof(_T)); printf("fieldinfo size : %d \n", _T::fieldinfo.size()); printf("struct layout : \n"); for (auto iter = _T::fieldinfo.begin(); iter != _T::fieldinfo.end(); iter++) { printf("%s, %s, %d \n", (*iter).name.c_str(), (*iter).type.c_str(), (*iter).offset); }}void main(){  PrintFieldInfo
(); Test test; ParaseToType
().Parase(test, "a=5;b=6.0f;c=766666666hhhhhgfdd"); printf("a = %d, b = %f, c = %s \n", test.a, test.b, test.c.c_str());}

转载于:https://my.oschina.net/lvan100/blog/219365

你可能感兴趣的文章
新书问答:Agile Management
查看>>
react入门
查看>>
VUE高仿饿了么app
查看>>
针对Kubernetes软件栈有状态服务设计的思考
查看>>
第八章 进程间通信
查看>>
POJ 2312Battle City(BFS-priority_queue 或者是建图spfa)
查看>>
CentOS 7 巨大变动之 firewalld 取代 iptables
查看>>
教你如何使用Flutter和原生App混合开发
查看>>
Spring Boot 整合redis
查看>>
CSS hover改变背景图片过渡动画生硬
查看>>
订单的子单表格设置颜色
查看>>
Office365 Exchange Hybrid 番外篇 ADFS后端SQL群集(一)
查看>>
lvs fullnat部署手册(三)rs内核加载toa篇
查看>>
SSL/TLS原理详解
查看>>
buildroot下查找外部编译器通过ext-toolchain-wrapper调用的参数
查看>>
iframe 在ie下面总是弹出新窗口解决方法
查看>>
android编译系统makefile(Android.mk)写法
查看>>
MD5源代码C++
查看>>
Eclipse 添加 Ibator
查看>>
Linux中变量$#,$@,$0,$1,$2,$*,$$,$?的含义
查看>>