源代码,cmake。github.com
什么时候使用回调函数?
case1:某厂家有一个设备的驱动,其中有一个函数function可以监控该设备的状态,当某事件event发生时,执行某一个“动作”action;然而,这个动作具体做什么是用户需要开发的;那么,厂家规定好这个动作的函数接口;用户开发好“动作”action的内容,在调用function时将action指针当作参数传入,这样当event发生时,action就会被执行。
case2:两个程序员同时开发一个项目,A做设备的驱动,B使用该设备,两个程序员可以一块规定好一个接口,即case1中action的接口;A做的驱动中函数function可以监控该设备的状态,当某事件event发生时,执行某一个“动作”action;B把action中具体要执行的内容开发好;B在调用function时将action指针当作参数传入,这样当event发生时,action就会被执行。这样,可以让两个程序员的工作解耦。
#pragma once
#include <iostream>
using namespace std;
typedef void(*ACTION)(void* callBackOwner);//A和Machine类约定接口,这个定义说明调用ACTION时,需要指定callBackOwner,即对象,是谁执行对象。
class Machine
{
public:
Machine();
~Machine();
void function(ACTION pAction, void* callbackOwner)//Machine中定义一个函数,当事件发生时,调用pAction,并指定是谁调用的
{
cout << "输入1,执行action" << endl;
int a = 0;
cin >> a;
if (a == 1)
{
pAction(callbackOwner);//函数(参数)形式,这样,即有了函数,又有了参数列表,就可以执行了
}
}
private:
};
Machine::Machine()
{
}
Machine::~Machine()
{
}
void action(void* lp);//前置声明
class A
{
public:
A();
~A();
std::string name;
void printname()
{
cout << name << endl;
}
void actionByA()
{
machine.function(action, this);
}
Machine machine;//machine是设备,设备能监控设备的事件,当某事件发生时,执行回调函数。
private:
};
A::A()
{
name = "frank";
}
A::~A()
{
}
void action(void* lp)
{
if (lp==NULL)
{
cout << "没有指定对象!" << endl;
return;
}
A* a = (A*)lp;
a->printname();
}
int main(void)
{
A a;
a.machine.function(action, &a);
a.actionByA();
Machine m;
m.function(action, NULL);//这样也能运行,只不过,不知道让谁执行action;如果没有对象A,可以执行别的事情
return 0;
}
![839916791548a953c9737a0f061da82b.png](https://i-blog.csdnimg.cn/blog_migrate/244271278b23d645bbc07efacc45c0cf.jpeg)
在Machine类中可以开放(regist)接口将函数指针和参数列表保存在变量中,测试代码如下:
#pragma once
#include <iostream>
using namespace std;
typedef void(*ACTION)(void* callBackOwner);//A和Machine类约定接口,这个定义中当调用ACTION时,需要指定callBackOwner,即对象,是谁执行对象。
class Machine
{
public:
Machine();
~Machine();
void function(ACTION pAction, void* callbackOwner)//Machine中定义一个函数,当事件发生时,调用pAction,并指定是谁调用的
{
cout << "输入1,执行action" << endl;
int a = 0;
cin >> a;
if (a == 1)
{
pAction(callbackOwner);//函数(参数)形式,这样,即有了函数,又有了参数列表,就可以执行了
}
}
void registOwner(void *owner)
{
cout << "注册函数" << endl;
cb_owner = owner;
}
void registActionAndOnwe(ACTION pAction, void* callbackOwner)
{
registOwner(callbackOwner);
this->pACTION = pAction;
}
void function(ACTION pAction)
{
cout << "输入1,执行action" << endl;
int a = 0;
cin >> a;
if (a == 1)
{
cout << "pAction"<< pAction << endl;
cout << "cb_owner" << cb_owner << endl;
pAction(cb_owner);//函数(参数)形式,这样,即有了函数,又有了参数列表,就可以执行了
}
}
void function()
{
cout << "本函数使用前,需要将函数和对象注册!" << endl;
if (pACTION==NULL)
{
cout << "pACTION未注册!" << endl;
return;
}
if (cb_owner==NULL)
{
cout << "cb_owner未注册!" << endl;
return;
}
cout << "输入1,执行action" << endl;
int a = 0;
cin >> a;
if (a == 1)
{
cout << "pAction" << pACTION << endl;
cout << "cb_owner" << cb_owner << endl;
pACTION(cb_owner);//函数(参数)形式,这样,即有了函数,又有了参数列表,就可以执行了
}
}
private:
void* cb_owner;
ACTION pACTION;
};
Machine::Machine()
{
}
Machine::~Machine()
{
}
void action(void* lp);//前置声明
class A
{
public:
A();
~A();
std::string name;
void printname()
{
cout << name << endl;
}
void actionByA()
{
machine.function(action, this);
}
void actionByA1()
{
machine.registOwner(this);
machine.function(action);
}
void actionByA2()
{
machine.registActionAndOnwe(action,this);
machine.function();
}
Machine machine;//machine是设备,设备能监控设备的事件,当某事件发生时,执行回调函数。
private:
};
A::A()
{
name = "frank";
}
A::~A()
{
}
void action(void* lp)
{
if (lp==NULL)
{
cout << "没有指定对象!" << endl;
return;
}
A* a = (A*)lp;//指针强制转换
a->printname();
}
int main(void)
{
A a;
//a.machine.function(action, &a);
a.actionByA1();
a.actionByA2();
//Machine m;
//m.function(action, NULL);//这样也能运行,只不过,不知道让谁执行action;如果没有对象A,可以执行别的事情
return 0;
}