再谈谈注册(本质是建立映射)与回调

        在之前的博文中, 我们探讨过映射的重要作用, 请直接看:http://blog.csdn.net/stpeace/article/details/39452203, 在那篇文章中, 我们是用STL中的map来做的, map建立的是key-value映射, 在本文中, 我们自己来建立映射, 并讨论一个更为复杂的程序, 顺便再次复习一下注册与回调。 

        注册与回调? 有那么复杂么?没有必要过多地扯了, 直接上代码:

 

#include <iostream>
#include <vector>
using namespace std;

// 前向声明
class BasicMod;


//类函数指针类型
typedef void (BasicMod:: *PFun)(const char* pParaName); 


// 映射结点
typedef struct
{
	BasicMod *pMod;
	char szParaName[1024];
	PFun operTypeOne;
	PFun operTypeTwo;
	PFun operTypeThree;
}MyMap;


// 用全局的g_pv保存结点指针
vector<MyMap *> g_pv;


// 执行类, 提供注册, 查找接口, 并执行回调操作
class Do
{
public:
	// 单例
	static Do *getInstance()
	{
		static Do *p = NULL;
		if(NULL == p)
		{
			p = new Do;
		}

		return p;
	}

	// 注册接口
	void regNode(BasicMod *pb, MyMap *pmap, int i)
	{
		MyMap *p = new MyMap;
		p->pMod = pb;
		memset(p->szParaName, 0, sizeof(p->szParaName));
		strncpy(p->szParaName, (pmap + i)->szParaName, sizeof(p->szParaName) - 1);
		p->operTypeOne = (pmap + i)->operTypeOne;
		p->operTypeTwo = (pmap + i)->operTypeTwo;
		p->operTypeThree = (pmap + i)->operTypeThree;

		g_pv.push_back(p);
	}

	// 查找接口
	MyMap *findNode(const char *pParaName)
	{
		int n = g_pv.size();
		int i = 0;
		for(i = 0; i < n; i++)
		{
			if(0 == strcmp(g_pv[i]->szParaName, pParaName))
			{
				return g_pv[i];
			}
		}

		return NULL;
	}

	// 执行回调操作
	void exect(const char *pParaName)
	{
		MyMap *p = findNode(pParaName);
		if(NULL != p && NULL != p->pMod)
		{
			((p->pMod)->*(p->operTypeOne))(pParaName);
			((p->pMod)->*(p->operTypeTwo))(pParaName);
			((p->pMod)->*(p->operTypeThree))(pParaName);
		}
	}
};


// 基类
class BasicMod
{
public:
	void reg(BasicMod *pm, MyMap *p, int i)
	{
		Do::getInstance()->regNode(pm, p, i);	
	}
};


// 格式化
#define TOGETHER(mod, name, f1, f2, f3) {NULL, name, (PFun)(&mod::f1), (PFun)(&mod::f2), (PFun)(&mod::f3)}


// 模块1
class Mod1 : public BasicMod
{
public:
	static Mod1* getInstance()
	{
		static Mod1* p = NULL;
		if(NULL == p)
		{
			p = new Mod1;
		}

		return p;
	}

	// 模块1的初始化
	void init()
	{
		MyMap mapArr[] = 
		{
			TOGETHER(Mod1, "cpu", fun1Cpu, fun2Cpu, fun3Cpu),
		};

		int n = sizeof(mapArr) / sizeof(mapArr[0]);
		int i = 0;
		for(i = 0; i < n; i++)
		{
			// 注册
			reg(getInstance(), mapArr, i);
		}
	}

	// 提供回调接口
	void fun1Cpu(const char *pParaName)
	{
		cout << "mod1, pParaName is " << pParaName << endl;
	}

	// 提供回调接口
	void fun2Cpu(const char *pParaName)
	{
		cout << "mod1, pParaName is " << pParaName << endl;
	}

	// 提供回调接口
	void fun3Cpu(const char *pParaName)
	{
		cout << "mod1, pParaName is " << pParaName << endl;
	}
};


class Mod2 : public BasicMod
{
public:
	static Mod2* getInstance()
	{
		static Mod2* p = NULL;
		if(NULL == p)
		{
			p = new Mod2;
		}

		return p;
	}

	void init()
	{
		MyMap mapArr[] = 
		{
			TOGETHER(Mod2, "flash", fun1Flash, fun2Flash, fun3Flash),
		};

		int n = sizeof(mapArr) / sizeof(mapArr[0]);
		int i = 0;
		for(i = 0; i < n; i++)
		{
			reg(getInstance(), mapArr, i);
		}
	}

	void fun1Flash(const char *pParaName)
	{
		cout << "mod2, pParaName is " << pParaName << endl;
	}

	void fun2Flash(const char *pParaName)
	{
		cout << "mod2, pParaName is " << pParaName << endl;
	}

	void fun3Flash(const char *pParaName)
	{
		cout << "mod2, pParaName is " << pParaName << endl;
	}
};


int main()
{
	// 模块初始化
	Mod1::getInstance()->init();
	Mod2::getInstance()->init();

	// 执行操作
	Do::getInstance()->exect("cpu");
	Do::getInstance()->exect("flash");
	Do::getInstance()->exect("mem");

	return 0;
}

 

      程序的结果为:

 

mod1, pParaName is cpu
mod1, pParaName is cpu
mod1, pParaName is cpu
mod2, pParaName is flash
mod2, pParaName is flash
mod2, pParaName is flash

        我们也可以对上述程序作一下等价变换, 得到:

 

#include <iostream>
#include <vector>
using namespace std;

// 前向声明
class BasicMod;


//类函数指针类型
typedef void (BasicMod:: *PFun)(const char* pParaName); 


// 映射结点
typedef struct
{
	BasicMod *pMod;
	char szParaName[1024];
	PFun operTypeOne;
	PFun operTypeTwo;
	PFun operTypeThree;
}MyMap;


// 用全局的g_pv保存结点指针
vector<MyMap *> g_pv;


// 执行类, 提供注册, 查找接口, 并执行回调操作
class Do
{
public:
	// 单例
	static Do *getInstance()
	{
		static Do *p = NULL;
		if(NULL == p)
		{
			p = new Do;
		}

		return p;
	}

	// 注册接口
	void regNode(BasicMod *pm, const char *pParaName, PFun one, PFun two, PFun three)
	{
		MyMap *p = new MyMap;
		p->pMod = pm;
		memset(p->szParaName, 0, sizeof(p->szParaName));
		strncpy(p->szParaName, pParaName, sizeof(p->szParaName) - 1);
		p->operTypeOne = one;
		p->operTypeTwo = two;
		p->operTypeThree = three;

		g_pv.push_back(p);
	}

	// 查找接口
	MyMap *findNode(const char *pParaName)
	{
		int n = g_pv.size();
		int i = 0;
		for(i = 0; i < n; i++)
		{
			if(0 == strcmp(g_pv[i]->szParaName, pParaName))
			{
				return g_pv[i];
			}
		}

		return NULL;
	}

	// 执行回调操作
	void exect(const char *pParaName)
	{
		MyMap *p = findNode(pParaName);
		if(NULL != p && NULL != p->pMod)
		{
			((p->pMod)->*(p->operTypeOne))(pParaName);
			((p->pMod)->*(p->operTypeTwo))(pParaName);
			((p->pMod)->*(p->operTypeThree))(pParaName);
		}
	}
};


// 基类
class BasicMod
{
public:
	void reg(const char *pParaName, PFun one, PFun two, PFun three)
	{
		Do::getInstance()->regNode(this, pParaName, one, two, three);	
	}
};


// 格式化
#define TOGETHER(mod, name, f1, f2, f3) {NULL, name, (PFun)(&mod::f1), (PFun)(&mod::f2), (PFun)(&mod::f3)}


// 模块1
class Mod1 : public BasicMod
{
public:
	static Mod1* getInstance()
	{
		static Mod1* p = NULL;
		if(NULL == p)
		{
			p = new Mod1;
		}

		return p;
	}

	// 模块1的初始化
	void init()
	{
		MyMap mapArr[] = 
		{
			TOGETHER(Mod1, "cpu", fun1Cpu, fun2Cpu, fun3Cpu),
		};

		int n = sizeof(mapArr) / sizeof(mapArr[0]);
		int i = 0;
		for(i = 0; i < n; i++)
		{
			// 注册
			reg(mapArr[i].szParaName, mapArr[i].operTypeOne, mapArr[i].operTypeTwo, mapArr[i].operTypeThree);
		}
	}

	// 提供回调接口
	void fun1Cpu(const char *pParaName)
	{
		cout << "mod1, pParaName is " << pParaName << endl;
	}

	// 提供回调接口
	void fun2Cpu(const char *pParaName)
	{
		cout << "mod1, pParaName is " << pParaName << endl;
	}

	// 提供回调接口
	void fun3Cpu(const char *pParaName)
	{
		cout << "mod1, pParaName is " << pParaName << endl;
	}
};


class Mod2 : public BasicMod
{
public:
	static Mod2* getInstance()
	{
		static Mod2* p = NULL;
		if(NULL == p)
		{
			p = new Mod2;
		}

		return p;
	}

	void init()
	{
		MyMap mapArr[] = 
		{
			TOGETHER(Mod2, "flash", fun1Flash, fun2Flash, fun3Flash),
		};

		int n = sizeof(mapArr) / sizeof(mapArr[0]);
		int i = 0;
		for(i = 0; i < n; i++)
		{
			reg(mapArr[i].szParaName, mapArr[i].operTypeOne, mapArr[i].operTypeTwo, mapArr[i].operTypeThree);
		}
	}

	void fun1Flash(const char *pParaName)
	{
		cout << "mod2, pParaName is " << pParaName << endl;
	}

	void fun2Flash(const char *pParaName)
	{
		cout << "mod2, pParaName is " << pParaName << endl;
	}

	void fun3Flash(const char *pParaName)
	{
		cout << "mod2, pParaName is " << pParaName << endl;
	}
};


int main()
{
	// 模块初始化
	Mod1::getInstance()->init();
	Mod2::getInstance()->init();

	// 执行操作
	Do::getInstance()->exect("cpu");
	Do::getInstance()->exect("flash");
	Do::getInstance()->exect("mem");

	return 0;
}

 

 

 

 

 

 

        我们看到, 上述程序建立了一个name对于{f1, f2, f3}的映射, 适用范围更广。 

        而且, 以后如果再加字段, 程序猿只需要注意三处即可: 1. 增加initialize函数中数组中的项(增加映射);2. 在类中实现回调接口(增加回调接口); 3.在main中启动调用(启动执行)

        当然啦, 如果要增加模块3, 那也是很easy的。

 

       反思一下:惊讶我突然发现, 我把上面的程序写复杂了, 其实, 也可以用STL map建立name到f1, f2, f3的映射, 此时, 要把{f1, f2, f3}看成一个整体, 上述程序用STL map进行改造后, 会更好, 有兴趣的朋友可以试试。 我相信: 一次刻骨铭心的体验胜过千百次说教。

 

 

 

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值