回调函数
关于这个东西,网上的教程真的太多了。这里我记录一个我觉得勉强有意思的,理解从理解函数指针到回调函数的过程。回调函数可以做很多东西,比如实现工厂模式,反射机制啊,某些种类的单例模式都可能用到。
反正挺无聊的。
1.理解函数指针
比如我要定义一个返回值为int 参数为(int, void*)的函数指针,一般都有三种写法
typedef int(*func)(int,void *);//1
using func = int(*)(int, void *);//2
using func = std::function(int(int, void *));//3
推荐使用第3中定义。这里可以不用加void*这个参数,我们先理解下函数指针。
#include <iostream>
#include <functional>
using func = std::function<int (int)>;
int getPow(int i){
return i*i;
}
int main(){
func f = getPow;
std::cout << f(6) << std::endl;
return 0;
}
输出结果:
36
看了这个示例可能就知道什么是函数指针了,我们重点不是这个。
2.面向过程,注册函数指针
先定义一个全局的函数指针,然后写一个注册函数,然后调用这个注册的函数。
#include <iostream>
#include <functional>
using func = std::function<int(int,void *)>;
func g_f;
void registPowCallBack(func f, void *ctx){
g_f = f;
}
int getPow(int i, void *){
return i*i;
}
int main(){
registPowCallBack(getPow,nullptr);
std::cout << g_f(5,nullptr) << std::endl;
return 0;
}
运行结果
25
3. 面向对象的CallBack
调用可分传递的是函数指针还是对象指针
3.1 传递对象指针
我们这样定义A类是计算,B类用于打印信息。我们在A中注册B的对象指针,这里我在B中定义string name标志是那个B的实例。在A中调用B进行打印。
#include <iostream>
#include <functional>
#include <string>
using func = std::function<int(int,void *)>;
/*
* define class B to print data
*/
template <typename T>
class B{
public:
explicit B(std::string name):name_(name){}
B(const B& )=delete;
void pritnData(T i){
std::cout << "by "<< this->name_ <<" "<<"the data is "<< i << std::endl;
}
private:
std::string name_;
};
template <typename T>
class A{
public:
explicit A(){};
A(const A& ) = delete;
private:
int getPow(int i, void *ctx){
B<T> *b = reinterpret_cast<B<T>*> (ctx);
if (nullptr != b){
b->pritnData(i*i);
}
return i*i;
}
public:
void regist_B_ptr(B<T>* b_ptr){
b_ = b_ptr;
//b_->pritnData(7);
}
public:
int getPow_A(int i){
return getPow(i,b_);
}
private:
B<int>* b_;
};
int main()
{
A<int>* a =new A<int>();
B<int>* b =new B<int>("this_B_00");
//b->pritnData(6);
a->regist_B_ptr(b);
a->getPow_A(2);
delete a;
delete b;
return 0;
}
4.利用回调机制实现static成员函数,对非静态成员函数或非静态成员的使用
#include <iostream>
#include <functional>
using func = std::function<int(int,void *)>;
//func g_f;
void callBack(func f, void* ctx){
//g_f = f;
std::cout<<f(5,ctx) << std::endl;
}
class A{
public:
static int getPow(int i, void* ctx){
A *a = reinterpret_cast<A*>(ctx);
return a->get_pow_impl(i);
}
private:
int get_pow_impl(int i){
return i*i;
}
public:
//注册
void regist(){
callBack(getPow,this);
}
private:
int num_ = 5;
};
int main(){
A* a = new A();
a->regist();
delete a;
return 0;
}
5 常见的callback写法
class A{
public:
//设置Callback函数到底是啥函数
void SetCallback(std::function<void(Event)> func){
event_callback_ = func;
}
protected:
//当已经设置了好了函数,调用的执行方法
void Callback(Event event) {
if (event_callback_) event_callback_(event);
}
private:
//声明callback 函数指针
std::function<void(Event)> event_callback_ = nullptr;
};