注册与回调

news/2024/7/20 21:32:01 标签: iphone, ios

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

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

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

复制代码

  1 #include <iostream>
  2 #include <vector>
  3 using namespace std;
  4  
  5 // 前向声明
  6 class BasicMod;
  7  
  8  
  9 //类函数指针类型
 10 typedef void (BasicMod:: *PFun)(const char* pParaName); 
 11  
 12  
 13 // 映射结点
 14 typedef struct
 15 {
 16     BasicMod *pMod;
 17     char szParaName[1024];
 18     PFun operTypeOne;
 19     PFun operTypeTwo;
 20     PFun operTypeThree;
 21 }MyMap;
 22  
 23  
 24 // 用全局的g_pv保存结点指针
 25 vector<MyMap *> g_pv;
 26  
 27  
 28 // 执行类, 提供注册, 查找接口, 并执行回调操作
 29 class Do
 30 {
 31 public:
 32     // 单例
 33     static Do *getInstance()
 34     {
 35         static Do *p = NULL;
 36         if(NULL == p)
 37         {
 38             p = new Do;
 39         }
 40  
 41         return p;
 42     }
 43  
 44     // 注册接口
 45     void regNode(BasicMod *pb, MyMap *pmap, int i)
 46     {
 47         MyMap *p = new MyMap;
 48         p->pMod = pb;
 49         memset(p->szParaName, 0, sizeof(p->szParaName));
 50         strncpy(p->szParaName, (pmap + i)->szParaName, sizeof(p->szParaName) - 1);
 51         p->operTypeOne = (pmap + i)->operTypeOne;
 52         p->operTypeTwo = (pmap + i)->operTypeTwo;
 53         p->operTypeThree = (pmap + i)->operTypeThree;
 54  
 55         g_pv.push_back(p);
 56     }
 57  
 58     // 查找接口
 59     MyMap *findNode(const char *pParaName)
 60     {
 61         int n = g_pv.size();
 62         int i = 0;
 63         for(i = 0; i < n; i++)
 64         {
 65             if(0 == strcmp(g_pv[i]->szParaName, pParaName))
 66             {
 67                 return g_pv[i];
 68             }
 69         }
 70  
 71         return NULL;
 72     }
 73  
 74     // 执行回调操作
 75     void exect(const char *pParaName)
 76     {
 77         MyMap *p = findNode(pParaName);
 78         if(NULL != p && NULL != p->pMod)
 79         {
 80             ((p->pMod)->*(p->operTypeOne))(pParaName);
 81             ((p->pMod)->*(p->operTypeTwo))(pParaName);
 82             ((p->pMod)->*(p->operTypeThree))(pParaName);
 83         }
 84     }
 85 };
 86  
 87  
 88 // 基类
 89 class BasicMod
 90 {
 91 public:
 92     void reg(BasicMod *pm, MyMap *p, int i)
 93     {
 94         Do::getInstance()->regNode(pm, p, i);    
 95     }
 96 };
 97  
 98  
 99 // 格式化
100 #define TOGETHER(mod, name, f1, f2, f3) {NULL, name, (PFun)(&mod::f1), (PFun)(&mod::f2), (PFun)(&mod::f3)}
101  
102  
103 // 模块1
104 class Mod1 : public BasicMod
105 {
106 public:
107     static Mod1* getInstance()
108     {
109         static Mod1* p = NULL;
110         if(NULL == p)
111         {
112             p = new Mod1;
113         }
114  
115         return p;
116     }
117  
118     // 模块1的初始化
119     void init()
120     {
121         MyMap mapArr[] = 
122         {
123             TOGETHER(Mod1, "cpu", fun1Cpu, fun2Cpu, fun3Cpu),
124         };
125  
126         int n = sizeof(mapArr) / sizeof(mapArr[0]);
127         int i = 0;
128         for(i = 0; i < n; i++)
129         {
130             // 注册
131             reg(getInstance(), mapArr, i);
132         }
133     }
134  
135     // 提供回调接口
136     void fun1Cpu(const char *pParaName)
137     {
138         cout << "mod1, pParaName is " << pParaName << endl;
139     }
140  
141     // 提供回调接口
142     void fun2Cpu(const char *pParaName)
143     {
144         cout << "mod1, pParaName is " << pParaName << endl;
145     }
146  
147     // 提供回调接口
148     void fun3Cpu(const char *pParaName)
149     {
150         cout << "mod1, pParaName is " << pParaName << endl;
151     }
152 };
153  
154  
155 class Mod2 : public BasicMod
156 {
157 public:
158     static Mod2* getInstance()
159     {
160         static Mod2* p = NULL;
161         if(NULL == p)
162         {
163             p = new Mod2;
164         }
165  
166         return p;
167     }
168  
169     void init()
170     {
171         MyMap mapArr[] = 
172         {
173             TOGETHER(Mod2, "flash", fun1Flash, fun2Flash, fun3Flash),
174         };
175  
176         int n = sizeof(mapArr) / sizeof(mapArr[0]);
177         int i = 0;
178         for(i = 0; i < n; i++)
179         {
180             reg(getInstance(), mapArr, i);
181         }
182     }
183  
184     void fun1Flash(const char *pParaName)
185     {
186         cout << "mod2, pParaName is " << pParaName << endl;
187     }
188  
189     void fun2Flash(const char *pParaName)
190     {
191         cout << "mod2, pParaName is " << pParaName << endl;
192     }
193  
194     void fun3Flash(const char *pParaName)
195     {
196         cout << "mod2, pParaName is " << pParaName << endl;
197     }
198 };
199  
200  
201 int main()
202 {
203     // 模块初始化
204     Mod1::getInstance()->init();
205     Mod2::getInstance()->init();
206  
207     // 执行操作
208     Do::getInstance()->exect("cpu");
209     Do::getInstance()->exect("flash");
210     Do::getInstance()->exect("mem");
211  
212     return 0;
213 }

复制代码

程序的结果为:

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

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

复制代码

  1 #include <iostream>
  2 #include <vector>
  3 using namespace std;
  4  
  5 // 前向声明
  6 class BasicMod;
  7  
  8  
  9 //类函数指针类型
 10 typedef void (BasicMod:: *PFun)(const char* pParaName); 
 11  
 12  
 13 // 映射结点
 14 typedef struct
 15 {
 16     BasicMod *pMod;
 17     char szParaName[1024];
 18     PFun operTypeOne;
 19     PFun operTypeTwo;
 20     PFun operTypeThree;
 21 }MyMap;
 22  
 23  
 24 // 用全局的g_pv保存结点指针
 25 vector<MyMap *> g_pv;
 26  
 27  
 28 // 执行类, 提供注册, 查找接口, 并执行回调操作
 29 class Do
 30 {
 31 public:
 32     // 单例
 33     static Do *getInstance()
 34     {
 35         static Do *p = NULL;
 36         if(NULL == p)
 37         {
 38             p = new Do;
 39         }
 40  
 41         return p;
 42     }
 43  
 44     // 注册接口
 45     void regNode(BasicMod *pm, const char *pParaName, PFun one, PFun two, PFun three)
 46     {
 47         MyMap *p = new MyMap;
 48         p->pMod = pm;
 49         memset(p->szParaName, 0, sizeof(p->szParaName));
 50         strncpy(p->szParaName, pParaName, sizeof(p->szParaName) - 1);
 51         p->operTypeOne = one;
 52         p->operTypeTwo = two;
 53         p->operTypeThree = three;
 54  
 55         g_pv.push_back(p);
 56     }
 57  
 58     // 查找接口
 59     MyMap *findNode(const char *pParaName)
 60     {
 61         int n = g_pv.size();
 62         int i = 0;
 63         for(i = 0; i < n; i++)
 64         {
 65             if(0 == strcmp(g_pv[i]->szParaName, pParaName))
 66             {
 67                 return g_pv[i];
 68             }
 69         }
 70  
 71         return NULL;
 72     }
 73  
 74     // 执行回调操作
 75     void exect(const char *pParaName)
 76     {
 77         MyMap *p = findNode(pParaName);
 78         if(NULL != p && NULL != p->pMod)
 79         {
 80             ((p->pMod)->*(p->operTypeOne))(pParaName);
 81             ((p->pMod)->*(p->operTypeTwo))(pParaName);
 82             ((p->pMod)->*(p->operTypeThree))(pParaName);
 83         }
 84     }
 85 };
 86  
 87  
 88 // 基类
 89 class BasicMod
 90 {
 91 public:
 92     void reg(const char *pParaName, PFun one, PFun two, PFun three)
 93     {
 94         Do::getInstance()->regNode(this, pParaName, one, two, three);    
 95     }
 96 };
 97  
 98  
 99 // 格式化
100 #define TOGETHER(mod, name, f1, f2, f3) {NULL, name, (PFun)(&mod::f1), (PFun)(&mod::f2), (PFun)(&mod::f3)}
101  
102  
103 // 模块1
104 class Mod1 : public BasicMod
105 {
106 public:
107     static Mod1* getInstance()
108     {
109         static Mod1* p = NULL;
110         if(NULL == p)
111         {
112             p = new Mod1;
113         }
114  
115         return p;
116     }
117  
118     // 模块1的初始化
119     void init()
120     {
121         MyMap mapArr[] = 
122         {
123             TOGETHER(Mod1, "cpu", fun1Cpu, fun2Cpu, fun3Cpu),
124         };
125  
126         int n = sizeof(mapArr) / sizeof(mapArr[0]);
127         int i = 0;
128         for(i = 0; i < n; i++)
129         {
130             // 注册
131             reg(mapArr[i].szParaName, mapArr[i].operTypeOne, mapArr[i].operTypeTwo, mapArr[i].operTypeThree);
132         }
133     }
134  
135     // 提供回调接口
136     void fun1Cpu(const char *pParaName)
137     {
138         cout << "mod1, pParaName is " << pParaName << endl;
139     }
140  
141     // 提供回调接口
142     void fun2Cpu(const char *pParaName)
143     {
144         cout << "mod1, pParaName is " << pParaName << endl;
145     }
146  
147     // 提供回调接口
148     void fun3Cpu(const char *pParaName)
149     {
150         cout << "mod1, pParaName is " << pParaName << endl;
151     }
152 };
153  
154  
155 class Mod2 : public BasicMod
156 {
157 public:
158     static Mod2* getInstance()
159     {
160         static Mod2* p = NULL;
161         if(NULL == p)
162         {
163             p = new Mod2;
164         }
165  
166         return p;
167     }
168  
169     void init()
170     {
171         MyMap mapArr[] = 
172         {
173             TOGETHER(Mod2, "flash", fun1Flash, fun2Flash, fun3Flash),
174         };
175  
176         int n = sizeof(mapArr) / sizeof(mapArr[0]);
177         int i = 0;
178         for(i = 0; i < n; i++)
179         {
180             reg(mapArr[i].szParaName, mapArr[i].operTypeOne, mapArr[i].operTypeTwo, mapArr[i].operTypeThree);
181         }
182     }
183  
184     void fun1Flash(const char *pParaName)
185     {
186         cout << "mod2, pParaName is " << pParaName << endl;
187     }
188  
189     void fun2Flash(const char *pParaName)
190     {
191         cout << "mod2, pParaName is " << pParaName << endl;
192     }
193  
194     void fun3Flash(const char *pParaName)
195     {
196         cout << "mod2, pParaName is " << pParaName << endl;
197     }
198 };
199  
200  
201 int main()
202 {
203     // 模块初始化
204     Mod1::getInstance()->init();
205     Mod2::getInstance()->init();
206  
207     // 执行操作
208     Do::getInstance()->exect("cpu");
209     Do::getInstance()->exect("flash");
210     Do::getInstance()->exect("mem");
211  
212     return 0;
213 }

复制代码

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

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

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

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


http://www.niftyadmin.cn/n/5257834.html

相关文章

Maven的settings.xml笔记231208

https://maven.apache.org/ref/ 官方文档的模板 官方文档模板3.9.6版 https://maven.apache.org/ref/3.9.6/maven-settings/settings.html The default location for the settings file is ~/.m2/settings.xml <settings xmlns"http://maven.apache.org/SETTINGS/1…

互联网加竞赛 opencv 图像识别 指纹识别 - python

0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于机器视觉的指纹识别系统 &#x1f947;学长这里给一个题目综合评分(每项满分5分) 难度系数&#xff1a;3分工作量&#xff1a;3分创新点&#xff1a;4分 该项目较为新颖&#xff0c;适…

CentOS使用kkFileView实现在线预览word excel pdf等

一、环境安装 1、安装LibreOffice wget https://downloadarchive.documentfoundation.org/libreoffice/old/7.5.3.2/rpm/x86_64/LibreOffice_7.5.3.2_Linux_x86-64_rpm.tar.gz # 解压缩 tar -zxf LibreOffice_7.5.3.2_Linux_x86-64_rpm.tar cd LibreOffice_7.5.3.2_Linux_x86…

消息队列kafka详解:Kafka架构介绍

一. 工作流程 Kafka中消息是以topic进行分类的&#xff0c;Producer生产消息&#xff0c;Consumer消费消息&#xff0c;都是面向topic的。 Topic是逻辑上的改变&#xff0c;Partition是物理上的概念&#xff0c;每个Partition对应着一个log文件&#xff0c;该log文件中存储的就…

idea打开控制台console的快捷键

默认是alt 4. 可以按如下方式修改

java系列-4种引用

在Java中&#xff0c;有四种类型的引用&#xff0c;它们分别是&#xff1a; 1. 强引用&#xff08;Strong Reference&#xff09; 强引用是最普遍的引用类型。通过强引用&#xff0c;对象将一直存在&#xff0c;直到没有任何强引用指向它。当JVM检测到没有强引用指向一个对象时…

kubernetes(k8s) Yaml 文件详解

YAML格式&#xff1a;用于配置和管理&#xff0c;YAML是一种简洁的非标记性语言&#xff0c;内容格式人性化&#xff0c;较易读。 1、查看API 资源版本标签 kubectl api-versions 2、编写资源配置清单 kubectl create -f nginx-test.yaml --validatefalse 2.3 查看创建的po…

MFC画折线图,基于x64系统

由于项目的需要&#xff0c;需要画一个折线图。 传统的Teechart、MSChart、HighSpeedChart一般是只能配置在x86系统下&#xff0c;等到使用x64系统下运行就是会报出不知名的错误&#xff0c;这个地方让人很苦恼。 我在进行配置的过程之中&#xff0c;使用Teechart将x86配置好…