一、基础类型反射
在前面以枚举体和函数进行了反射的实践,在其中也提到过,其实更应该进行反射的是类(结构体)。毕竟现在以面向对象编程基本已经普及,类(结构体)的应用几乎已经是无法避免的。所以对类(后面再提到类即包含结构体)的反射,其实应用的范围会更大。
对基础类型和POD类型的结构体进行反射,一般就是下面的情况:
1、对名称进行反射来动态获取和创建对象
2、对结构体变量的反射
这里只是POD类型的结构体,复杂的在后面再进行分析,当然这里也包含简单类。
二、实现机制
在前面反复进行反射的分析说明时,其实可以发现,反射实现常用的机制还是比较多的,但一般来说应用的比较多的就是使用模板和宏配合来实现。当然在具体的实现过程中可能需要一些具体的编译器或者辅助库的实现。另外在c++新标准下也提供了一些方法比如可以使用std::tuple来实现类的反射。
其实原理仍然是前面分析过的文章中的思路,即获取名称字符串与结构体之间的映射,其成员(变量)需要进行遍历注册。这样就可以在后面的代码中利用字符串来搞定这些对象获取及动态创建对象等。
这里需要再次说明的是:
1、是否需要侵入式处理
2、是否开销最小甚至是零开销
3、是否反射完全,即包括私有数据等是否可以得到
这三个条件是实现一个好的反射框架的前提。
三、实现
下面看一个初步的实现:
#pragma once
#include <string>
#include <array>
#include <stddef.h>
#include <iostream>
typedef unsigned int uint32;
struct Type {
std::string typeName;
size_t size;
};
//获得结构体成员类型信息
template<typename T>
Type* GetFieldType();
#define GET_OBJECT_TYPE(TYPE) \
template<> \
Type* GetFieldType<TYPE>() {
\
static Type t; \
t.typeName = #TYPE; \
t.size = sizeof(TYPE); \
return &t; \
};\
//成员反射信息
struct Member {
Type* t;
std::string name;
size_t offset;
};
constexpr int ARRAY_NUM = 4;
// 存储结构体的相关成员
struct