flyman

opengl world
随笔 - 10, 文章 - 0, 评论 - 65, 引用 - 0
数据加载中……

C++ 类成员的CALLBACK

这几天在用CEGUI,学习了一下他的CALLBACK原理,写了一个小CASE
FOLLOWING IS IT:
  1 // main.cpp : Defines the entry point for the console application.
  2 //
  3 
  4 #include "stdafx.h"
  5 #include <string>
  6 #include <iostream>
  7 #include <map>
  8 
  9 class MessageMap//功能类,调用对象
 10 {
 11 public:
 12     MessageMap()
 13     {
 14 
 15     }
 16     ~MessageMap()
 17     {
 18 
 19     }
 20     int print(int para1,int para2)
 21     {
 22         std::cout<<"Para1="<<para1<<std::endl;
 23         std::cout<<"para2="<<para2<<std::endl;
 24         return 1;
 25     }
 26 
 27     int add(int para1,int para2)
 28     {
 29         std::cout<<"para1+para2="<<para1+para2<<std::endl;
 30         return 1;
 31     }
 32 };
 33 
 34 typedef int (MessageMap::*MemberFunction)(int ,int );//Callback函数原型
 35 
 36 class FuncCode//函数的从属关系
 37 {
 38 
 39 public:
 40     FuncCode(MessageMap* pObj,MemberFunction pFun)
 41     {
 42         obj=pObj;
 43         fun=pFun;
 44     }
 45 public:
 46 
 47     MessageMap* obj;
 48     MemberFunction fun;
 49 };
 50 
 51 class SendMessage//调用类
 52 {
 53 public:
 54     SendMessage()
 55     {
 56 
 57     }
 58     ~SendMessage()
 59     {
 60         FunMapIterator itend=funmap.end();
 61         for (FunMapIterator it=funmap.begin ();it!=itend;it++)
 62         {
 63             delete it->second;
 64         }
 65         funmap.clear ();
 66     }
 67     int addMessageFunction(std::string msg,int (MessageMap::*fun)(int,int),MessageMap* pobj)
 68     {
 69         funmap[msg]=new FuncCode(pobj,fun);
 70         return 1;
 71     }
 72      int operator()(std::string msg,int para1,int para2)
 73     {
 74          return ((funmap[msg]->obj)->*(funmap[msg]->fun))(para1,para2);
 75         
 76     }
 77 protected:
 78     typedef std::map<std::string,FuncCode*> FunMap;
 79     typedef std::map<std::string,FuncCode*>::iterator FunMapIterator;
 80     FunMap funmap;
 81 };
 82 
 83 int _tmain(int argc, _TCHAR* argv[])
 84 {
 85     MessageMap* pObj= new MessageMap();
 86     SendMessage SendMsg;
 87     {//初始化
 88         SendMsg.addMessageFunction ("print",&MessageMap::print,pObj);
 89         SendMsg.addMessageFunction ("add",&MessageMap::add,pObj);
 90     }
 91 
 92     {//调用
 93         SendMsg("print",1,2);
 94         SendMsg("add",1,2);
 95     }
 96 
 97     delete pObj;
 98     return 0;
 99 }
100 
101 //说明
102 //1、这种调用可以用类模板扩展,其实这是一个CALLBACK简略版,有兴趣的话可以参考CEGUI源码,里面用的是类模板
103 //,这样的话将不再受类型(MESSAGEMAP)的限制。
104 //
105 //2、对于int addMessageFunction(std::string msg,int (MessageMap::*fun)(int,int),MessageMap* pobj)
106 //的参数问题,主要说明int (MessageMap::*fun)(int,int)。
107 //这是一个很有意思的参数,他的类型为int (MessageMap::*)(int,int),值为 fun,有兴趣的可以看看ASM的传参过程
108 //,其实这里可以用MemberFunction fun代替,当然用模板的话会有所不同,参考CEGUI.
109 //3.不要把typedef int (MessageMap::*MemberFunction)(int ,int ) 定义成
110 //typedef int (*MemberFunction)(int ,int ),这是代码的关键所在,一般的C++BOOK都会提及他们的不同之处。
111 
112 
113 
114 


posted on 2007-08-10 20:57 flyman 阅读(3693) 评论(5)  编辑 收藏 引用

评论

# re: C++ 类成员的CALLBACK  回复  更多评论   

总结的不错, 比较巧妙的例子
2007-08-10 23:27 | SmartPtr

# re: C++ 类成员的CALLBACK  回复  更多评论   

不错,写的非常的好!
2007-08-13 09:34 | 梦在天涯

# re: C++ 类成员的CALLBACK  回复  更多评论   

其实主要是使用了.*或者是-〉*操作符的表达式。
2007-08-21 09:51 | SuperPlayeR

# re: C++ 类成员的CALLBACK  回复  更多评论   

不错的例子
2007-09-23 09:32 | 蚂蚁终结者

# re: C++ 类成员的CALLBACK  回复  更多评论   


template < class Class, typename ReturnType, typename Parameter1, typename Parameter2 >
class CallBack < Class, ReturnType, Parameter1, Parameter2, void >
{

public:

typedef ReturnType (Class::*Method)(Parameter1,Parameter2);

CallBack(Class* _class_instance, Method _method)
{
class_instance = _class_instance;
method = _method;
};

ReturnType operator()(Parameter1 parameter1, Parameter2 parameter2)
{
return (class_instance->*method)(parameter1, parameter2);
};

ReturnType execute(Parameter1 parameter1, Parameter2 parameter2)
{
return operator()(parameter1, parameter2);
};

private:

Class* class_instance;
Method method;

};

typedef CallBack<MessageMap, int, int, int> callback;

MessageMap messageMap;
vector<callback> callbackList;
callbackList.push_back(callback(&messageMap,&MessageMap::add));
callbackList.push_back(callback(&messageMap,&MessageMap::print));

for (unsigned int i =0; i<callbackList.size(); i++)
{
callbackList[i].execute(1, 2);

}


// more simpler?
2009-01-07 06:29 | vistors

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   博问   Chat2DB   管理