在之前的一篇回调函数简单例子中就写了一个简单的回调小例子,这里补充一下。

一个对象的this指针并不是对象本身的一部分,不会影响sizeof(对象)的结果。this作用域是在类内部,当在类的非静态成员函数中访问类的非静态成员的时候,编译器会自动将对象本身的地址作为一个隐含参数传递给函数。也就是说,即使你没有写上this指针,编译器在编译的时候也是加上this的,它作为非静态成员函数的隐含形参,对各成员的访问均通过this进行。

为了实现回调,我们必须把this指针给转换掉!可为了在该函数中可以直接操作该类中的成员,我们必须保留this指针!所以这是矛盾的。

在类封装回调函数:

a.回调函数只能是全局的或是静态的。
 b.全局函数会破坏类的封装性,故不予采用。
 c.静态函数只能访问类的静态成员,不能访问类中非静态成员

让静态函数访问类的非静态成员的方法:

在消息回调的函数参数中传递一个该类的指针即可,就像类中创建一个多线程的回调一样.将类的指针传递给该回调函数,然后用该指针调用类的非静态成员函数和指针.或者用一个类的全局指针数组,保存每一个创建出来的类的this指针,用全局指针去调用。如下:

class A()

回调函数中访问非静态成员

由于回调函数往往有固定定义,并不接受  A * pThis 参数
   如:CALLBACK MyTimerProc(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime);
【解决方案1】:本方案当遇到有多个类实例对象时会有问题。原因是pThis指针只能指向一个对象。
  class A()
  {
      static void a(); //静态回调函数
      void b();  //非静态函数 
      static A * pThis;   //静态对象指针
  }  
  
  A * A::pThis=NULL;  //这句话必须要在cpp一开始就写,不然编译会报无法解析的外部符号的错。
  A::A()   //构造函数中将this指针赋给pThis,使得回调函数能通过pThis指针访问本对象
  {
       pThis=this;
  }
  void A::a()
  {
      if (pThis==NULL) return;
      pThis->b(); //回调函数中调用非静态函数 
  }
【解决方案2】:本方案解决多个类实例对象时方案1的问题。用映射表存所有对象地址,每个对象保存自己的ID号。
  typedef CMap<UINT,UINT,A*,A*> CAMap;
  class A()
  {
      static void a(); //静态回调函数
      void b();  //非静态函数 
      int m_ID;  //本对象在列表中的ID号
      static int m_SID;   //静态当前对象ID        (需要时,将m_ID赋值给m_SID以起到调用本对象函数的功能)
      static CAMap m_Map; //静态对象映射表
  }  
  
  CAMap A::m_Map;
  int   A::m_SID=0;
  
 
  A::A()   //构造函数中将this指针赋给pThis,使得回调函数能通过pThis指针访问本对象
  {
      if(m_Map.IsEmpty())
      {
   m_ID=1;
      }
      else
      { 
        m_ID=m_Map.GetCount()+1;
      }
      m_Map.SetAt( m_ID, this );
  }
 void A::a()
  {
      if (m_Map.IsEmpty()) return;
      A * pThis=NULL;
      if(m_Map.Lookup(m_SID,pThis))
      {
   pThis->b(); //回调函数中调用非静态函数 
      };
  }

原文连接:https://blog.csdn.net/u012072012/article/details/45537387

回调函数必须要用static的原因相关推荐

  1. lwIP 细节之三:TCP 回调函数是何时调用的

    使用 lwIP 协议栈进行 TCP 裸机编程,其本质就是编写协议栈指定的各种回调函数.将你的应用逻辑封装成函数,注册到协议栈,在适当的时候,由协议栈自动调用,所以称为回调. 注:除非特别说明,以下内容 ...

  2. Java对C语言Dll的加载 和 回调函数的使用

    C语言HWPuSDK.h文件: #ifndef _HW_PU_SDK_H_ #define _HW_PU_SDK_H_#pragma pack(push,4)#ifdef _WIN32// for w ...

  3. C++回调函数(callback)的使用

    什么是回调函数(callback)      模块A有一个函数foo,它向模块B传递foo的地址,然后在B里面发生某种事件(event)时,通过从A里面传递过来的foo的地址调用foo,通知A发生了什 ...

  4. jQuery $.post()返回类型为json时不进入回调函数的原因及解决方法

    jQuery $.post()返回类型为json时不进入回调函数的原因及解决方法 参考文章: (1)jQuery $.post()返回类型为json时不进入回调函数的原因及解决方法 (2)https: ...

  5. c++类的成员函数作回调函数为啥要声明为static的

    简单说明 C++的类成员函数不能像普通函数那样用于回调,因为每个成员函数都需要有一个对象实例去调用它. 把成员函数作为回调函数,可以把该成员函数声明为静态成员函数,但这样做有一个缺点,就是会破坏类的结 ...

  6. C++ 实现把非静态成员函数作为回调函数(非static)

    众所周知,C++的类成员函数不能像普通函数那样用于回调,因为每个成员函数都需要有一个对象实例去调用它. 通常情况下,要实现成员函数作为回调函数,一种常用的方法就是把该成员函数设计为静态成员函数,但这样 ...

  7. 李老三借钱吃麻辣烫但不耽误回家喂熊猫,原因竟是他会回调函数!!

    大家好,我是永远吃不饱的小胖鱼. 这两天在写<动手学ROS2>教程的时候,一会冒出来一个回调函数. 因为担心未来的读者们被回调函数绕晕,小鱼今天就特意把回调函数拎出来说一说. 顺便说一说什 ...

  8. 回调函数 线程_从0实现基于Linux socket聊天室-多线程服务器一个很隐晦的错误-2...

    根据 <0 基于socket和pthread实现多线程服务器模型>所述,server创建子线程的时候用的是以下代码: pconnsocke = (int *) malloc(sizeof( ...

  9. QT信号与槽——观察者模式——回调函数

    QT信号与槽--观察者模式--回调函数 1.QT信号与槽机制 1.1信号本质 信号是由于用户对窗口或控件进行了某些操作,导致窗口或控件产生了某个特定事件,这时候 Qt 对应的窗口类会发出某个信号.比如 ...

最新文章

  1. RSTP的根保护功能
  2. vue项目-点击添加或者修改按钮浏览器的屏幕变黑,再次点击屏幕之后浏览器恢复正常(火狐浏览器、ChromeCoreLauncher双核浏览器)
  3. 搜索,然后学习:两阶段的无监督文本生成
  4. 文件与文件夹课后作业
  5. 为啥一到年底腾讯市值就大涨??????
  6. Visual Studio Code 快捷键的设置
  7. 高可用性、负载均衡的mysql集群解决方案
  8. php的转义字符quot;反斜杠quot;是,php如何去除转义字符中的反斜杠
  9. Matplotlib——基本用法
  10. 导致页面顶部空白一行解决方法
  11. Galaxy Fold上市时间推延 屏幕瑕疵是主因
  12. 网络流 增广路 入门很好的文章
  13. 在线文件管理系统 下载地址
  14. 05 Confluent_Kafka权威指南 第五章: kafka内部实现原理
  15. 北大计算机前辈徐,九年中获得国家最高科学技术奖的八位北大人
  16. LibPcap丢包问题
  17. uniapp:轮播里如何加入视频
  18. eureka client无法启动,java.lang.IllegalStateException: Failed to introspect Class
  19. 淘宝特价版将接入微信 腾讯会松口吗?
  20. NightWatchJS

热门文章

  1. 【GO语言学习】使用GO语言输出Emoji表情
  2. CRC算法 个人学习笔记 直接法、查表法注意点
  3. 基于JAVA酒店后厨供应商订单合并系统计算机毕业设计源码+系统+mysql数据库+lw文档+部署
  4. 续章一区百战金牌指挥·盟重土城
  5. php.ini development,php.ini-development、php.ini-production、php.ini-dist,php.ini-
  6. create connection SQLException, url: jdbc:mysql://127.0.0.1:3306/xxxx, errorCode 0, state 08001
  7. 远程计算机后无法正常播放声音,求大神远程电脑修声音,放电视都没声音,但QQ音乐有声音...
  8. 能够背熟对你的学习很有好处的
  9. 运维学习 之 Ngnix配置(详细版)
  10. Android开源框架集合分享-图像加载