• C++ 注册回调函数机制


    回调函数机制 使用了 函数指针
    步骤:

    • 1.定义一个函数指针,如typedef void (*func_ptr)(std::string str);
    • 2.定义一个 回调函数 void func(std::string str),需要注意的是,回调函数必须和前面定义的函数指针参数类型和参数个数一致
    • 3.定义一个注册回调函数 void SetCallback(func_ptr ptr);, 其中 func_ptr 是一个函数指针类型,之后会把一个回调函数地址(函数名func)赋值给 ptr
     1 typedef void (*func_ptr)(std::string str);
     2 
     3 class Test{
     4  func_ptr m_ptr;
     5 
     6  void SetCallback(func_ptr ptr){
     7     this->m_ptr = ptr;  // 注册回调函数把传入的函数指针 ptr 赋值给了成员函数m_ptr
     8   }
     9 }
    10 
    11 // 在其他地方或其他cpp文件定义一个下面这样的函数 
    12 void func(std::string str)
    13 {
    14     /*code*/
    15 }
    16 
    17 int main(){
    18   Test test;
    19   test.SetCallback(func);
    20 }

      如:SetCallback(func) 把 一个已经定义的函数func的函数地址 赋值给 函数指针 m_ptr,这样就相当于注册了回调函数,当我们在对象的其他位置就可以直接以函数形式调用m_ptr("Jack")了。
    所以注册回调函数SetCallback(func_ptr ptr)的作用就是 给成员变量函数指针进行赋值,相当于对是对对象实现回调函数,以便后面直接调用该回调函数。

      如果要在两个class对象之间传递数据,最简单直接的方法在一个类中定义一个全局变量,然后在另一个类里面extern这个变量,这样就等于这个全局变量同时作用于两个类对象中,这样做能暂时解决问题,然而可能会出现新的问题,比如,代码的复用性不好,全局变量会在main之前初始化,增加了程序的负担;还有一个致命的问题,如果是多线程程序,就需要加锁保证同一时刻只能有一个对象在访问修改这个全局变量,程序的效率可能会下降,当然如果定义的全局变量过多,由于加锁不慎很可能会导致死锁,致使程序奔溃,今天介绍一中很实用的办法,线程安全并且封装性好;

      先看代码

     1 #include <iostream>    
     2 
     3 using namespace std;  
     4 
     5 typedef void(*CallBack)(char* s);
     6 
     7 class A{
     8 public:
     9   void setCbk(CallBack call_back){
    10       this->_my_call_back = call_back;
    11       _my_call_back("123456789");
    12   }
    13 public:
    14   A(){}
    15   ~A(){}
    16   CallBack _my_call_back;
    17 };
    18 
    19 class  B{
    20 public:
    21   static void OnCallBack(char * s){
    22       cout << "gxs s:" << s << endl;
    23   }
    24 
    25 public:
    26   B(){        
    27       A a;
    28       a.setCbk(B::OnCallBack);    //注册回调函数
    29   }
    30   ~B(){}
    31 };
    32 
    33 int main()
    34 {
    35   B b;
    36   return 0;
    37 }

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

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

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

  • 相关阅读:
    第一个小程序-简单计算器
    You have to be inside an angular-cli project in order to use the serve command.
    执行命令npm install typescript@2.3.1 --save-dev,发现了不得了的东西
    安装gulp或者npm淘宝镜像cnpm时出现错误,proxy was not installed probaly
    @angular/compiler-cli@4.3.6 requires typescript@'>=2.1.0 <2.4.0' but 2.5.2 was found instead.
    The "@angular/compiler-cli" package was not properly installed. Error: TypeError: Cannot read property 'Private' of undefined
    angula安装各种包出现"Please try running this command again as root/Administrator."的解决方法
    The “@angular/compiler-cli” package was not properly installed
    关于angular开发中报错Cannot find module 'webpack/lib/node/NodeTemplatePlugin'问题的解决办法若干
    psql:定位慢查询
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/16572760.html
Copyright © 2020-2023  润新知