【c++】16.回调函数、注册回调函数
回调函数机制 使⽤了 函数指针。
步骤:
1.定义⼀个函数指针,如typedef void (*func_ptr)(std::string str);
2.定义⼀个 回调函数 void func(std::string str),需要注意的是,回调函数必须和前⾯定义的函数指针参数类型和参数个数⼀致
3.定义⼀个注册回调函数 void SetCallback(func_ptr ptr);, 其中 func_ptr 是⼀个函数指针类型,之后会把⼀个回调函数地址(函数
名func)赋值给 ptr;指针函数的作用
typedef void(*func_ptr)(std::string str);
class Test{
func_ptr m_ptr;
void SetCallback(func_ptr ptr){
this->m_ptr = ptr;// 注册回调函数把传⼊的函数指针 ptr 赋值给了成员函数m_ptr
}
}
// 在其他地⽅或其他cpp⽂件定义⼀个下⾯这样的函数
void func(std::string str)
{
/*code*/
}
int main(){
Test test;
test.SetCallback(func);
}
如:SetCallback(func) 把 ⼀个已经定义的函数func的函数地址 赋值给 函数指针 m_ptr,这样就相当于注册了回调函数,当我们在对象的其他位置就可以直接以函数形式调⽤m_ptr("Jack")了。
所以注册回调函数SetCallback(func_ptr ptr)的作⽤就是 给成员变量函数指针进⾏赋值,相当于对是对对象实现回调函数,以便后⾯直接调⽤该回调函数。
后来我看到我同事的⼀篇博客,写得挺不错,粘贴于此
如果要在两个class对象之间传递数据,最简单直接的⽅法在⼀个类中定义⼀个全局变量,然后在另⼀个类⾥⾯extern这个变量,这样就等于这个全局变量同时作⽤于两个类对象中,这样做能暂时解决问题,然⽽可能会出现新的问题,⽐如,代码的复⽤性不好,全局变量会在main之前初始化,增加了程序的负担;还有⼀个致命的问题,如果是多线程程序,就需要加锁保证同⼀时刻只能有⼀个对象在访问修改这个全局变量,程序的效率可能会下降,当然如果定义的全局变量过多,由于加锁不慎很可能会导致死锁,致使程序奔溃,今天介绍⼀中很实⽤的办法,线程安全并且封装性好;
先看代码
#include <iostream>
using namespace std;
typedef void(*CallBack)(char* s);
class A{
public:
void setCbk(CallBack call_back){
this->_my_call_back = call_back;
_my_call_back("123456789");
}
public:
A(){}
~
A(){}
CallBack _my_call_back;
};
class  B{
public:
static void OnCallBack(char* s){
cout <<"gxs s:"<< s << endl;
}
public:
B(){
A a;
a.setCbk(B::OnCallBack);//注册回调函数
}
~B(){}
};
int main()
{
B b;
return0;
}
⾸先typedef void(*CallBack)(char* s)申明了⼀个函数指针,这个CallBack指针指向⼀个返回值是void类型参数是char*的函数;那怎么才能让类A的char*数据传到类B来呢,读代码就知道了,很简单在类A⾥⾯定义⼀个CallBack的成员变量,然后把类B的OnCallBack的地址赋值给A的CallBack,这样A的Cal
lBack在执⾏的时候就会执⾏B的OnCallBack的代码了;
该怎么理解呢? 理解这个原理⾸先得理解函数指针的含义,顾名思义,函数指针它是⼀个指针,这个指针指向的是⼀个函数。这个意思就是,你可以通过⼀个指针去调⽤⼀个函数,所以你想调⽤别的类的函数,就要把它类⾥⾯这个函数的地址获取到赋值到你类⾥⾯的函数指针。
其实,这是回调函数最原始的做法,很多IDE已经开发出⾮常⾼效便捷的回调形式,最经典的莫过于Qt的信号槽机制了,它做的太好了,好到你可以任意的设置回调的接⼝⽽不必关⼼这个谁去发起这个连接,换句话说就是: 你在Class A中设置回调的时候class B这个对象不存在也没关系

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。