注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

还东国的博客

行之苟有恒,久久自芬芳

 
 
 

日志

 
 

类成员的回调函数  

2011-08-05 11:18:16|  分类: C++(VC)编程 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

类成员的回调函数
一般来讲,类成员函数由于默认带有一个this指针,从而造成回调的失败,但有种情况是可以解决这个问题的,那就是使用静态变量,由于静态的成员变量和静态成员函数,是类

本身的变量,一量定义,其地址就不会再改变,所以可以使用做为回调函数。
不过,我们要注意的是,使用回调和静态函数,以及友元函数,都破坏了对象封装性,是不符合面向对象的设计思想的,所以说,应该还是尽量避免这种情况的发生,在实际下,

一般都可以使用传递成员变量或其指针、引用的方法来达到同样的目的。
回到今天的话题,有两种方法可以实现,一种是使用静态成员变量,一种是使用静态成员函数,但得到的效果是一样的,其本质也是相同的,先说第一种。
一、使用静态成员变量。
有如下代码:
先定义回调函数指针:
typedef void (CALLBACK *pFunCallBack)(void* pOwner);
然后将其定义到使用类上,如下:
pFunCallBack m_pFun;
再在使用的类中定义同样的一个静态成员变量供使用:
CDialogMyCall *pInt;
在类外初始化:
CDialogMyCall *CDialogMyCall::pInt = NULL;
然后类似于单实例一样,在构造函数里:
pInt = this;
将真正的值赋给他。
再设定一个函数,全局或其它可以使用的(直接在初始化函数指针的位置使用也可以)都可以来初始化函数指针
void SetCallBack(pFunCallBack pFun)
{
 (CDialogMyCall::pInstance)->m_pFun = pFun;
}
然后我们再写一个具体的回调函数,这才是真正的馅儿:
void __stdcall g_CallBack(void*pOwner)
{
 CDialogMyCall* pInt = (CDialogMyCall*)pOwner;
 if (pInt == NULL)
 {
  return;
 }

 pInt->GetDlgItem(IDC_EDIT1)->SetWindowTextA("111111111");

}

注意的是,回调函数的调用方式必须是CALLBACK即__stdcall 这种形式。至于为什么是这种形式,还有其它哪种形式,这里不讲,大家有兴趣可以自己去看书。
整个的操作过程是:
先通过SetCallBack(g_CallBack)初始化函数指针,然后在真实使用函数指针的地方,调用if (m_pFun != NULL) m_pFun(void*(this)),然后就可以达到我们的效果了,这个东东看

起来和c#的委托,是不是非常相象啊。
第二种,静态成员函数方法
有如下代码:
定义函数指针:
typedef void (CALLBACK* ONSERIESREAD)(CWnd*,BYTE* buf,int bufLen);
然后定义其成员变量:
ONSERIESREAD m_OnSeriesRead;

然后我们使用其的类中定义一个静态成员函数:
static void OnSeriesRead(CWnd* pWnd, BYTE* buf,int bufLen);
在某个初始化的过程里:
this->m_ceSeries.m_OnSeriesRead = OnSeriesRead;
这就好说了,关键是,这里使用的是静态成员函数,如何访问非静态的成员变量或者函数呢,(更详细的请参阅“静态成员如何访问非静态成员变量方法”)
最简单的方法就进直接把当前的对象指针传到你的静态成员函数中去:
可以再用一个初始化函数在你的函数指针的定义对象中:
比如这里的OPEN函数,将THIS指针传过去,但一定千万千万一定得注意,要判断指针的值,否则,程序的崩溃是正常的。
其实这两种方法都是变相传递了当前的类对象的指针,与我们开头讲的传递指针是异曲同工的,没什么神秘之处。

  评论这张
 
阅读(981)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017