C++类对象反制机制实现_精简修改版

前几天写的类对象反射机制太烦锁了,今天写个修改版的,精简为两个类
一个是类的数据结构,另一个是类的父类对象,把所有操作类的方法都写到父类中

1.类的信息结构体

struct Field_Node
{
	TCHAR m_name[20];		//字段名称
	TCHAR m_typeName[20];	// 字段类型名称
	size_t m_typeHashCode;	//字段数据类型的哈希值
	size_t m_typeOffs;		//字段偏移量
};

字段信息结构不再添加其他方法了,就只为保存字段信息数据

2.父类QObject

class QObject
{
public:
	QObject(){}
	virtual ~QObject(){}

public:
	//静态方法获取子类对象,直接New一个子类对象就好了
	template<typename T>
	static QObject* CreateObject(){
		retrun new T();
	}

	//纯虚函数获得子类的字段信息数组地址
	virtual const Field_Node* GetSubClassFieldNode()const=0;

	//设置类对象的字段数据
	template<typename T>
	void Set_Value(const TCHAR* strFieldName, const T& inValue){
		//调用子类的,获得其静态的字段信息数组地址
		const Field_Node* pField=GetSubClassFieldNode(); 
		//循环查找字段名称并给其赋值
		while(pField->m_typeHashCode!=0){
			if(lstrcmp(pField->m_name,strFieldName)==0){
				if(pField->m_typeHashCode!=typeid(T).hash_code()){
					assert(false && "数据类型不匹配,检查字段数据类型和输入的数据类型是否一致!!!");
					return;
				}
				
				//设置字段的值
				*((T*)((unsigned char*)&stu+ pField->m_typeOffs))=inValue;
				return;
			}
			pField++;
		}//end while
	}

	//获得字段数据
	void Get_Value(const TCHAR* strFieldName, T& outValue){
		//调用子类的,获得其静态的字段信息数组地址
		const Field_Node* pField=GetSubClassFieldNode(); 
		//循环查找字段名称并给其赋值
		while(pField->m_typeHashCode!=0){
			if(lstrcmp(pField->m_name,strFieldName)==0){
				if(pField->m_typeHashCode!=typeid(T).hash_code()){
					assert(false && "数据类型不匹配,检查字段数据类型和输入的数据类型是否一致!!!");
					return;
				}
				
				//获取字段的值
				outValue=*((T*)((unsigned char*)&stu+ pField->m_typeOffs));
				return;
			}
			pField++;
		}//end while
	}


	
};

这样就能对子类对象的字段进行数据操作了

3.下面是类的注册宏,在其内就重写一个父类的虚函数就搞定了,

//类内声明宏
#define REGISTER_CLASS_NAME()\
public:\
const Field_Node* GetSubClassFieldNode()const

//类外实现宏
#define BEGIN_REGISTER_FILEDS_NAME(class_name)\
const Field_Node* class_name::GetSubClassFieldNode()const{\
typedef class_name thisClass;\
static const Field_Node thisClass##Field_Node[]={\


//结束宏
#define END_REGISTER_FILEDS_NAME()\
{TEXT(""),TEXT(""),0,0}};return &thisClass##Field_Node[0];}

//添加字段信息结构宏
#define ADD_FIELD_NAME(fName,fType)\
{TEXT(#fName),TEXT(#fType),typeid(fType).hash_code(),(size_t)&((thisClass*)0)->fName},\

//TEXT(#fName) 字段名称(变量的名称,name,sex)
//TEXT(#fType) 数据类型名称(int ,bool)
//(size_t)&((thisClass*)0)->fName 字段的偏移量
//typeid(fType).hash_code() 获得数据类型的哈希值,用来比较数据类型是否相同

4.用法就更加简单了,

class Student :public QOBject{
REGISTER_CLASS_NAME()
public:
	Student(){}
	~Student(){}
public:
	int id;
	CString name;
	CString sex;
	UINT age;
};

BEGIN_REGISTER_FILEDS_NAME(Student)
	ADD_FIELD_NAME(id, int)
	ADD_FIELD_NAME(name, CString)
	ADD_FIELD_NAME(sex, CString)
	ADD_FIELD_NAME(age, UINT)
END_REGISTER_FILEDS_NAME()


//测试函数中

//通过父类的静态方法获取子类New的对象
//用父类指针来操作子类对象进行赋值,获取值等操作
QOject* pObj=QObject::CreateObject<Student>();

//给对象赋值
pObj->Set_Value(TEXT("id"),123);
pObj->Set_Value(TEXT("name"),CString(TEXT("张三")));
pObj->Set_Value(TEXT("sex"),CString(TEXT("男")));
pObj->Set_Value(TEXT("id"),(UINT)33);

//获取对象字段的值
Student s;
pObj->Get_Value(TEXT("id"),s.id);
pObj->Get_Value(TEXT("name"),s.name);
pObj->Get_Value(TEXT("sex"),s.sex);
pObj->Get_Value(TEXT("id"),s.age);

//最后操作完可转化子类对象指针
Student *pStu=(Student*)pObj;

总结一下是不是比前面[写的简单多了,也容易弄懂,
其实关键是获取子类的结构信息,用纯虚函数就能调用子类的静态字段结构数组,
也就相对简单了,

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值