动态创建宏的简单实现

本文介绍了使用C++实现动态创建对象的方法,通过定义类结构和静态变量保存类名及创建函数指针。利用模板函数进行类型转换,提供查找并执行创建函数的机制。示例代码展示了如何注册和创建`UObject`及其派生类`hi`的实例。
练习的动态创建,从字符串创建对象的实现用一个类里面的静态变量保存所有注册过的类的类名和创建函数的指针
//u.h
#pragma once
#include <string>
#include <map>

using std::string;
using std::map;
using std::pair;

//强制转换模板函数
template<class Dest, class Src>
Dest force_cast(Src src)
{
	union
	{
		Dest d;
		Src s;
	} convertor;

	convertor.s = src;
	return convertor.d;
}

//创建结构,保存每个类的类名和其动态创建函数的指针
class createnode{
public:
	createnode(string str,string str2,void * fn)
		:classname(str)
		,baseclassname(str2)
		,pfn(fn)
	{}

	string classname;
	string baseclassname;
	void *pfn;
};

//保存所有的类的创建结构
class infor
{

public:
	typedef map<string ,void *> infotype;
	typedef map<string ,string> parentinfortype;
	static infotype* getinfor()
	{
		static  infotype allclass;
		return &allclass;
	}
	static parentinfortype* getparentinfor(){
		static  parentinfortype pallclass;
		return &pallclass;
	}
private:
	infor(){};
};

//提供获取创建函数信息的方法
class all
{
public:
	all(createnode *node)
	{
		//allclass.insert(pair<string,void *>(node->classname,node->pfn));

		infor::getinfor()->insert(pair<string,void *>(node->classname,node->pfn));	
		infor::getparentinfor()->insert(pair<string,string>(node->classname,node->baseclassname));
	}

	static void *findfunc(string str)
	{
		void* fn ;
		//map<string , void *>::iterator i = allclass.find(str);

		map<string , void *>::iterator i = infor::getinfor()->find(str);
		fn = i->second;
		return fn;
	}
	//static bool iskindof()
	
	//static map<string ,void *> allclass;
};

//map<string ,void *> all::allclass;



//////////////////////////////////////////////////////////////////////////////////////////////
//所有注册的类型的全局的动态创建函数
template<class T>
T* g_createObject(string str)
{
	typedef T* (*fn)(void);
	fn cfn= force_cast<fn>(all::findfunc(str));
	T *obj = NULL;
	if (cfn)
	{
		obj = (*cfn)();
	}
	return obj;

}

class UObject;
UObject *g_testfind(string str)
{
	typedef UObject* (*fn)(void);
	fn cfn = force_cast<fn>(all::findfunc(str));
	UObject *obj = NULL;
	if (cfn)
	{
		obj = (*cfn)();
	}	
	return obj;
}




//////////////////////////////////////////////////////////////////////////////////////////
//问题:通过字符串找到创建函数指针后任然需要做一次强制转换
//可以声明返回值为UObject* ,
#define  DYN_DECLARE_CREATE(classname)\
public:\
	static classname * createobject##classname(){\
	classname *p = new classname;\
	return p;\
}\
private:\
	static all classname##all;\
	

//baseclassname没用到

#define  DYN_IMPLEMENT_CREATE(classname,baseclassname)\
	all classname::classname##all(\
	new createnode(#classname,#baseclassname,force_cast<void *>(classname::createobject##classname)));

///////////////////////////////////////////////////////////////////////////////////////////

//串行化?
//class USerial
//{
//public:
//	USerial& operator>>(UObject *classname){return classname->serialize(*this);}
//};
//
//#define DECLARE_SERIAL(classname)\
//public:\
//	friend USerial& operator>>(classname,USerial &us);\
//	virtual USerial& serialize(USerial &us);
//
//
//#define IMPLEMENT_SERIAL(classname)\
//	
//object.h
#include "u.h"

class UObject
{
	DYN_DECLARE_CREATE(UObject)
public:
	UObject()
	{
		std::cout<<"UObject construct!"<<std::endl;
	};
	virtual  ~UObject()
	{

	};

	string getObjectName() const {return objectName;}
	void setObjectName(string str) {objectName = str;}

	virtual void donothing() {};

private:
	string objectName;
};

DYN_IMPLEMENT_CREATE(UObject,UObject)


//main.cpp
#include <iostream>

#include "object.h"


class hi : public UObject
{
	DYN_DECLARE_CREATE(hi)

public:
	hi()
	{
		std::cout<<"hi construct"<<std::endl;
	}
	~hi()
	{
		std::cout<<"hi delete"<<std::endl;
	}
	virtual void donothing(){};
};

DYN_IMPLEMENT_CREATE(hi,UObject)



int main()
{


	UObject *ua = g_createObject<UObject>("UObject");

	hi * a = g_createObject<hi>("hi");


	UObject * b = g_createObject<UObject>("hi");

	UObject *c = g_testfind("hi");

	if (ua && a && b && c)
	{	
		std::cout<<"dynamic creating methods works !"<<std::endl;
	}
	else
	{
		std::cout<<"oops! failed to create object!"<<std::endl;
	}

	std::cin.get();
	return	0;
}
运行结果:



评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值