http://blog.chinaunix.net/uid-22488454-id-3057473.html
1). 不使用成员函数,直接使用普通C函数,为了实现在C函数中可以访问类的成员变量,可以使用友元操作符(friend),在C++中将该C函数说明为类的友元即可。这种处理机制与普通的C编程中使用回调函数一样。
2). 使用静态成员函数,静态成员函数不使用this指针作为隐含参数,这样就可以作为回调函数了。静态成员函数具有两大特点:其一,可以在没有类实例的情况下使用;其二,只能访问静态成员变量和静态成员函数,不能访问非静态成员变量和非静态成员函数。由于在C++中使用类成员函数作为回调函数的目的就是为了访问所有的成员变量和成员函数,如果作不到这一点将不具有实际意义。解决的办法也很简单,就是使用一个静态类指针作为类成员,通过在类创建时初始化该静态指针,如pThis=this,然后在回调函数中通过该静态指针就可以访问所有成员变量和成员函数了。这种处理办法适用于只有一个类实例的情况,因为多个类实例将共享静态类成员和静态成员函数,这就导致静态指针指向最后创建的类实例。为了避免这种情况,可以使用回调函数的一个参数来传递this指针,从而实现数据成员共享。这种方法比较麻烦。
简单的c语言回调函数
- /*
- * main.cc
- *
- * Created on: 2011-12-1
- * Author: simondu
- */
-
- #include "head.h"
- //#include "test5.cc"
-
- using namespace std;
- typedef int (*Fn)(char *p);
- int callbackfn(Fn fn ,char *p)
- {
-
- fn(p);
- }
- int callbackfn2(int(*ptr)(char* p), char* str)
- {
- (*ptr)(str);
-
- }
- int Afun(char *p)
- {
- printf("%s\n",p);
- return 0;
- }
-
- int main(int argc, char* argv[])
- {
- printf("Starting...... \n");
- char *str = "hello world";
- callbackfn(Afun,str);
- callbackfn2(Afun,str);
- printf("Ending...... \n");
- return 0;
- }
c++ 写的一个简单的回调函数
- /*
- * main.cc
- *
- * Created on: 2011-12-1
- * Author: simondu
- */
-
- #include "head.h"
-
-
- class CTest;
- typedef void (CTest::*DoMessageFunc)(char* msg, int msgid );
- class CTest
- {
- public:
- CTest(){}
- ~CTest(){}
- void DoMsgFunc1(char* pMsg,int nID)
- {
- printf("%s\n",pMsg);
- printf("回调函数\n");
- }
-
- void RegiestMsg(int nSrcID,DoMessageFunc pFunc)
- {
- m_pFunc = pFunc;
- }
-
- void HandleMessage(int nMsgID, char* pMsg, int nID)
- {
- (this->*m_pFunc)(pMsg,nID);
- }
- private:
- DoMessageFunc m_pFunc;
- };
-
- using namespace std;
-
-
- int main(int argc, char* argv[])
- {
- printf("Starting...... \n");
- CTest obj ;
- obj.RegiestMsg(12,&CTest::DoMsgFunc1);
- obj.HandleMessage(1,"test",6);
- printf("Ending...... \n");
- return 0;
- }
刚刚在网上看到C++回调函数的描述非常的好
转载自 http://bbs.bccn.net/thread-152948-1-1.html
- void CallBack::AddCallBack(char *event,CallBackFunction cbf,CallBack *p);
- void CallBack::AddCallBack(char *event,CallBackStaticFunction cbsf);
- void CallBack::RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p);
- void CallBack::RemoveCallBack(char *event,CallBackStaticFunction cbsf);
- void CallBack::RemoveCallBack(char *event);
- /*
- * callback.h
- *
- * Created on: 2012-1-12
- * Author: simondu
- */
-
- #ifndef CALLBACK_H_
- #define CALLBACK_H_
-
- #include<stdlib.h>
- #include<string.h>
- #include<iostream.h>
- #define CALLBACKLIST_INIT_SIZE 10
- #define CALLBACKLIST_INCREMENT 5
- class CallBack;
- typedef void *CallData;//回调数据指针类型定义
- typedef void (CallBack::*CallBackFunction)(CallData); //指向回调成员函数的指针
- typedef void (*CallBackStaticFunction)(CallData); //指向静态成员函数或普通函数的指针类型定义
-
- class EventRecord{
- private:
- char *eventName; //回调事件名称
- CallBack *pointerToCBO;//指向回调对象的指针
- //指向成员函数的指针和指向静态成员函数(或普通函数)指针的共用体
- union{
- CallBackFunction pointerToCBF;
- CallBackStaticFunction pointerToCBSF;
- };
- public:
- EventRecord(void); //事件记录类的缺省构造函数
- //构造包含成员函数的事件记录
- EventRecord(char *ename,CallBack *pCBO,CallBackFunction pCBF);
- //构造包含静态成员函数或普通函数的事件记录
- EventRecord(char *ename,CallBackStaticFunction pCBSF);
- ~EventRecord(void);//析构事件记录
- void operator = (const EventRecord& er);//重载赋值运算符
- //判断当前事件记录的事件名是否为ename
- int operator == (char *ename) const;
- //判断当前事件记录是否和指定事件记录相等
- int operator == (const EventRecord& er) const;
- void Flush(void); //将当前事件记录清空
- int IsEmpty(void) const;//判断事件记录是否为空(即事件名是否为空)
- friend class CallBack; //让CallBack类能访问EventRecord的私有成员;
-
- };
-
- class CallBack {
- private:
- EventRecord *callBackList; //回调事件表
- int curpos; //当前事件记录位置
- int lastpos; //回调表中最后一空闲位置
- int size; //回调表的大小
- void MoveFirst(void) { curpos = 0; }//将当前记录置为第一条记录
- void MoveNext(void) //将下一条记录置为当前记录
- {
- if(curpos == lastpos) return;
- curpos++;
- }
- //判断回调表是否被遍历完
- int EndOfList(void) const { return curpos == lastpos; }
- public:
- CallBack(void);//构造函数
- CallBack(const CallBack& cb);//拷贝构造函数
- ~CallBack(void);//析构函数
- void operator = (const CallBack& cb);// 重载赋值运算符
- //将回调对象的成员函数、静态成员函数(或普通函数)
- //注册为事件对象的回调函数
- void AddCallBack(char *event,CallBackFunction cbf,CallBack *p);
- void AddCallBack(char *event,CallBackStaticFunction cbsf);
- //删除注册在指定事件上的回调函数
- void RemoveCallBack(char *event,CallBackFunction cbf,CallBack *p);
- void RemoveCallBack(char *event,CallBackStaticFunction cbsf);
- void RemoveCallBack(char *event);// 删除某事件的全部记录
- //执行注册在某一事件上的所有回调函数
- void CallCallBack(char *event, CallData calldata = NULL);
- };
-
- #endif /* CALLBACK_H_ */
- /*
- * callback.cpp
- *
- * Created on: 2012-1-12
- * Author: simondu
- */
-
- #include "callback.h"
-
- EventRecord::EventRecord(void)
- {
- eventName = NULL;
- pointerToCBO = NULL;
- //因为sizeof(CallBackFunction) > sizeof(CallBackStaticFunction)
- pointerToCBF = NULL;
- }
- EventRecord::EventRecord(char *ename, CallBack *pCBO, CallBackFunction pCBF)
- :pointerToCBO(pCBO), pointerToCBF(pCBF)
- {
- eventName = strdup(ename);
- }
- EventRecord::EventRecord(char *ename, CallBackStaticFunction pCBSF)
- :pointerToCBO(NULL), pointerToCBSF(pCBSF)
- {
- eventName = strdup(ename);
- }
- EventRecord::~EventRecord(void)
- {
- if(eventName) delete eventName;
- }
- void EventRecord::operator = (const EventRecord& er)
- {
- if(er.eventName)
- eventName = strdup(er.eventName);
- else
- eventName = NULL;
- pointerToCBO = er.pointerToCBO;
- pointerToCBF = er.pointerToCBF;
- }
- int EventRecord::operator == (char *ename) const
- {
- if((eventName == NULL)||ename == NULL)
- return eventName == ename;
- else
- return strcmp(eventName,ename) == 0;
- }
- int EventRecord::operator == (const EventRecord& er) const
- {
- return (er == eventName) /*er和eventname不能交换位置*/
- &&(pointerToCBO == er.pointerToCBO)
- &&(pointerToCBO ?
- (pointerToCBF == er.pointerToCBF):
- (pointerToCBSF == er.pointerToCBSF));
- }
- void EventRecord::Flush(void)
- {
- if(eventName){
- delete eventName;
- eventName = NULL;
- }
- pointerToCBO = NULL;
- pointerToCBF = NULL;
- }
- int EventRecord::IsEmpty(void) const
- {
- if(eventName == NULL)
- return 1;
- else
- return 0;
- }
- //Callback类的实现
- CallBack::CallBack(void)
- {
- //按初始尺寸为回调表分配内存空间
- callBackList = new EventRecord[CALLBACKLIST_INIT_SIZE];
- if(!callBackList){
- cerr<<"CallBack: memory allocation error."<<endl;
- exit(1);
- }
- size = CALLBACKLIST_INIT_SIZE;
- lastpos = 0;
- curpos = 0;
- }
- CallBack::CallBack(const CallBack& cb): curpos(cb.curpos),lastpos(cb.lastpos),size(cb.size)
- {
- callBackList = new EventRecord[size];
- if(!callBackList){
- cerr<<"CallBack: memory allocation error."<<endl;
- exit(1);
- }
- //一一复制各条事件记录
- for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i];
- }
- void CallBack::operator = (const CallBack& cb)
- {
- curpos = cb.curpos;
- lastpos = cb.lastpos;
- size = cb.size;
- delete [] callBackList;//删除旧的回调表
- callBackList = new EventRecord[size];//重新分配内存空间
- if(!callBackList){
- cerr<<"CallBack: memory allocation error."<<endl;
- exit(1);
- }
- //一一复制各条事件记录
- for(int i = 0; i < size; i++) callBackList[i] = cb.callBackList[i];
- }
- CallBack::~CallBack(void)
- {
- delete [] callBackList;
- }
- void CallBack::AddCallBack(char *event, CallBackFunction pCBF, CallBack *pCBO)
- {
- //如事件名为空,退出
- if( (event == NULL)?1:(strlen(event) == 0)) return;
- //寻找因删除事件记录而产生的第一个空闲位置,并填写新事件记录
- int start=0;
- for(start=0; start < lastpos; start++ )
- if(callBackList[start].IsEmpty()){
- callBackList[start] = EventRecord(event,pCBO,pCBF);
- break;
- }
- if(start < lastpos) return; //确实存在空闲位置
- //没有空闲位置,在回调表后追加新记录
- if(lastpos == size) //回调表已满,需“伸长”
- {
- EventRecord *tempList = callBackList;//暂存旧回调表指针
- //以一定的步长“伸长”回调表
- callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];
- if(!callBackList){
- cerr<<"CallBack: memory allocation error."<<endl;
- exit(1);
- }
- //复制旧回调表中的记录
- for(int i = 0; i < size; i++) callBackList[i] = tempList[i];
- delete [] tempList;//删除旧回调表
- size += CALLBACKLIST_INCREMENT;//记下新回调表的尺寸
- }
- //构造新的事件记录并将其填入回调表中
- callBackList[lastpos] = EventRecord(event,pCBO,pCBF);
- lastpos++;
- }
- void CallBack::AddCallBack(char *event,CallBackStaticFunction pCBSF)
- {
- if( (event == NULL)?1:(strlen(event) == 0)) return;
- int start=0;
- for(start = 0; start<lastpos; start++)
- if(callBackList[start].IsEmpty()){
- callBackList[start] = EventRecord(event,pCBSF);
- break;
- }
- if(start < lastpos) return; //a hole is found
- if(lastpos == size) //event list is insufficient
- {
- EventRecord *tempList = callBackList;
- callBackList = new EventRecord[size + CALLBACKLIST_INCREMENT];
- if(!callBackList){
- cerr<<"CallBack: memory allocation error."<<endl;
- exit(1);
- }
- for(int i = 0; i < size; i++) callBackList[i] = tempList[i];
- delete [] tempList;
- size += CALLBACKLIST_INCREMENT;
- }
- callBackList[lastpos] = EventRecord(event,pCBSF);
- lastpos++;
- }
- //删除注册在指定事件上的成员函数
- void CallBack::RemoveCallBack(char *event, CallBackFunction pCBF, CallBack *
- pCBO)
- {
- if( (event == NULL)?1:(strlen(event) == 0)) return;
- EventRecord er(event,pCBO,pCBF);
- for(int i = 0; i < lastpos; i++)
- if(callBackList[i] == er) callBackList[i].Flush();
- }
- //删除注册在指定事件上的静态成员函数或普通函数
- void CallBack::RemoveCallBack(char *event,CallBackStaticFunction pCBSF)
- {
- if( (event == NULL)?1:(strlen(event) == 0)) return;
- EventRecord er(event,pCBSF);
- for(int i = 0; i < lastpos; i++)
- if(callBackList[i] == er) callBackList[i].Flush();
- }
- //删除注册在指定事件上的所有回调函数
- void CallBack::RemoveCallBack(char *event)
- {
- if( (event == NULL)?1:(strlen(event) == 0)) return;
- for(int i = 0; i < lastpos; i++)
- if(callBackList[i] == event) callBackList[i].Flush();
- }
- void CallBack::CallCallBack(char *event, CallData callData)
- {
- if( (event == NULL)?1:(strlen(event) == 0)) return;
- CallBack *pCBO;
- CallBackFunction pCBF;
- CallBackStaticFunction pCBSF;
- MoveFirst();
- while(!EndOfList())
- {
- //如当前事件记录和指定事件不匹配,转入下一条记录继续循环
- if(!(callBackList[curpos] == event))
- {
- MoveNext();
- continue;
- }
- //如找到匹配记录
- pCBO = callBackList[curpos].pointerToCBO;
- //如事件记录中回调对象指针为空,说明该记录中保存的是静态函数指针
- if(pCBO == NULL)
- {
- pCBSF = callBackList[curpos].pointerToCBSF;
- pCBSF(callData);//调用该静态回调函数
- }
- else //如事件记录中回调对象指针非空,说明该记录中保存的是成员函数指针
- {
- pCBF = callBackList[curpos].pointerToCBF;
- (pCBO->*pCBF)(callData);// 调用该回调对象的成员函数
- }
- MoveNext();
- }
- }
- /*
- * test5.cc
- *
- * Created on: 2012-1-11
- * Author: simondu
- */
-
-
- #include "head.h"
- #include"callback.h"
- class Speaker:public CallBack
- {
- private:
- int volume;
- public:
- Speaker(int v): volume(v) {}
- void IncreaseVolume(int v) //增加音量成员函数
- {
- volume += v;
- if(volume > 20){
- //“音量大于20”事件发生了
- //调用注册在两事件上的回调函数
- CallCallBack("音量改变了");
- CallCallBack("音量大于20", &volume);
- }
- }
- void DecreaseVolume(int v) //降低音量成员函数
- {
- volume -= v;
- if(volume < 5){ //“音量小于5”事件发生了
- //调用注册在两事件上的回调函数
- CallCallBack("音量改变了");
- CallCallBack("音量小于5", &volume);
- }
- }
- };
- //“耳朵”类
- class Ear : public CallBack
- {
- public:
- static void Response(CallData callData) //对“音量改变”的反应
- {
- cout<<"音量改变了."<<endl;
- }
- void HighVoiceResponse(CallData callData)//对高音的反应
- {
- cout<<"喂!太吵了!现在音量是:"<<*((int *)callData)<<endl;
- }
- void LowVoiceResponse(CallData callData)// 对低音的反应
- {
- cout<<"啊!我听不清了。现在音量是:"<<*((int *)callData)<<endl;
- }
- };
- /*
- * main.cc
- *
- * Created on: 2011-12-1
- * Author: simondu
- */
-
- #include "head.h"
- #include "test5.cc"
-
- using namespace std;
-
- int main(int argc, char* argv[])
- {
- printf("Starting...... \n");
- Speaker s(10); //现在音量为10
- Ear e;
- //为事件对象s注册回调函数
- s.AddCallBack("音量大于20",(CallBackFunction)&Ear::HighVoiceResponse,&e);
- s.AddCallBack("音量小于5",(CallBackFunction)&Ear::LowVoiceResponse,& e);
- s.AddCallBack("音量改变了",(CallBackStaticFunction)&Ear::Response);
- s.IncreaseVolume(12);//将音量增加12,现在音量位22
- s.DecreaseVolume(20);//将音量减少20,现在音量位2
-
- printf("Ending...... \n");
- return 0;
- }