【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)的作用就是 给成员变量函数指针进行赋值,相当于对是对对象实现回调函数,以便后面直接调用该回调函数。

后来我看到我同事的一篇博客,写得挺不错,粘贴于此

原文地址:c++两个普通类利用回调函数传递信息https://blog.csdn.net/M_Alan_walker/article/details/108320295

       如果要在两个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;
  return 0;
}

       首先typedef void(*CallBack)(char* s)申明了一个函数指针,这个CallBack指针指向一个返回值是void类型参数是char*的函数;那怎么才能让类Achar*数据传到类B来呢,读代码就知道了,很简单在类A里面定义一个CallBack的成员变量,然后把类BOnCallBack的地址赋值给ACallBack,这样ACallBack在执行的时候就会执行BOnCallBack的代码了;

       该怎么理解呢? 理解这个原理首先得理解函数指针的含义,顾名思义,函数指针它是一个指针,这个指针指向的是一个函数。这个意思就是,你可以通过一个指针调用一个函数,所以你想调用别的类的函数,就要把它类里面这个函数的地址获取到赋值到你类里面的函数指针。

       其实,这是回调函数最原始的做法,很多IDE已经开发出非常高效便捷的回调形式,最经典的莫过于Qt信号槽机制了,它做的太好了,好到你可以任意的设置回调的接口而不必关心这个谁去发起这个连接,换句话说就是: 你在Class A中设置回调的时候class B这个对象不存在也没关系

  • 10
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
文件: ActnList CreateAction 函数 创建一个指定类型的Action,显示在action list editor中。 EnumRegisteredAction 过程 枚举已经注册的Action RegisterAction 过程 注册Action UnRegisterAction 过程 反注册Action 文件: Classes Bounds 函数 输入上下高宽返回一个矩形结构。 CollectionsEqual 函数 比较两个TCollection是不是相等。 CurrentGroup 变量 FindClass 函数 从输入字符串中返回一个从TPersistent继承的类 FindGlobalComponent 变量 返回一个最高阶的容器类。 GetClass 函数 返回一个已经注册了的从TPersistent继承的类 LineStart 函数 返回下一行的开始字符位置 ObjectBinaryToText 过程 转换对象的二进制流形式到文件。 ObjectResourceToText 过程 转换对象的二进制资源到文件。 ObjectTextToBinary 过程 转换保存对象的文件形式到二进制流。 ObjectTextToResource 过程 转换保存对象的文件形式到资源。 Point 函数 输入X,y坐标返回一个点结构。 ReadComponentRes 函数 从窗口资源中读出一个控件和她的属性。 ReadComponentResEx 函数 同上 ReadComponentResFile 函数 从窗口资源文件中读出一个控件和她的属性。 Rect 函数 输入上下左右返回一个矩形结构 RegisterClass 过程 注册一个从TPersistent继承的类,使她的类的类型能够被识别。 RegisterClassAlias 过程 注册一个和另一个除了名字外都相同的类。 RegisterClasses 过程 注册一组类 RegisterComponents 过程 注册一组控件 RegisterIntegerConsts 过程 RegisterNoIcon 过程 注册一组没有图标的控件 RegisterNonActiveX 过程 防止一组控件被ActiveX wizard识别。 UnregisterClass 过程 反注册一个类 UnregisterClasses 过程 反注册一组类 UnregisterModuleClasses 过程 反注册定义在模块中的所有的类 WriteComponentResFile 过程 写控件和她的属性到文件。 文件: Clipbrd Clipboard 函数 返回一个TClipboard对象 SetClipboard 函数 用一个新TClipboard替换全局TClipboard。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值