回调函数注册,再次开帖

zrdongjiao 2012-07-01 10:39:52


昨天问了个回调注册 的问题,大家都说,c++没有注册这个概念,是windows的。

找了篇博客 ,看了会,有的地方没有搞懂。

这是博客内容.



CGameStart中有个CCommu 类指针,CCommu 中有函数指针数组。

CGameStart 里定义了一些静态函数指针。 Init函数 然后把这些指针,赋值给CCommu 的成员函数指针
数组。

最后以以下方式
if(pGame->pCommu->func_list[CB_MOVE] != NULL)//回调函数的触发
{
pGame->pCommu->func_list[CB_MOVE](pGame->pCommu->func_args[CB_MOVE]);
}

来调用 CGameStart 的成员函数。


问题:作者绕这么多弯子, 到底干嘛,直接调用CGameStart的函数即可, 感觉 回调注册,是否是闲着没事干,研究的技巧。。

我菜鸟,不懂作者意图,大神帮忙解答。




//def.h   
#include <iostream>
#include <stdio.h>
using namespace std;

typedef enum
{
CB_MOVE = 0, //
CB_COMEBACK, //
CB_BUYEQUIIP, //
}cb_type;

typedef void(*cb_func)(void *);

class CCommu //模块类
{
public:
CCommu()
{
memset(func_list, 0, sizeof(cb_func) *(CB_BUYEQUIIP +1));
memset(func_args, 0, sizeof(void *) *(CB_BUYEQUIIP +1));
}

int reg_cb(cb_type type, cb_func func, void *args = NULL)//注册回调函数
{
if(type <= CB_BUYEQUIIP)
{
func_list[ type ] = func;
func_args[type] = args;
return 0;
}
}
public:
cb_func func_list[CB_BUYEQUIIP + 1] ; //函数指针数组
void * func_args[CB_BUYEQUIIP +1];
};




//Gamestart.h
#include "def.h"

class CGameStart
{

public:
CGameStart();
~CGameStart();
void Init();
void run();
void Execute();

//一些回调函数
void static Move(void *args);
void static Comeback(void *args);
void static Buyequip(void *args);

public:
CCommu *pCommu;

};



//Gamestart.cpp
#include "Gamestart.h"

CGameStart::CGameStart():pCommu(NULL)
{}

void CGameStart::Init() //初始化的时候,注册回调函数
{
pCommu = new CCommu;
pCommu ->reg_cb(CB_MOVE, Move , this);
pCommu->reg_cb (CB_COMEBACK, Comeback,this );
}

void CGameStart::run()
{
Init();
}

void CGameStart::Execute()
{
cout<<"callback funciton is running"<<endl;

}
CGameStart::~CGameStart()
{
if(pCommu != NULL)
{
delete pCommu;
pCommu = NULL;
}
}

void CGameStart::Move(void *args)
{
CGameStart *pGame = (CGameStart *)args;
pGame -> Execute();
}
void CGameStart::Comeback(void *args)
{
//char *str = (char *)args;
//cout << str <<endl;
}






//main.cpp
#include "Gamestart.h"


int main()
{

CGameStart *pGame = new CGameStart;
pGame -> run();
if(pGame->pCommu->func_list[CB_MOVE] != NULL)//回调函数的触发
{
pGame->pCommu->func_list[CB_MOVE](pGame->pCommu->func_args[CB_MOVE]);
}
return 0;
}
...全文
844 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
jun5love 2013-05-03
  • 打赏
  • 举报
回复
谁给解释下:代码第13行 "typedef void(*cb_func)(void *); " typedef 有什么作用啊?看不明白。
zrdongjiao 2012-07-01
  • 打赏
  • 举报
回复

貌似是高手,

高手,再问个事情,



把已经发生的事通知用户,把正在发生的事交给用户处理


已经发生了什么事情???

正在发生了什么事情?


程序最终给用户使用, 用户操作的只是一个界面程序。

我始终不懂, 所谓通知,如何通知的,

windows中有SendMessage,可以告诉某个窗口,





[Quote=引用 7 楼 的回复:]
我个人理解
回调函数更多的适用于和用户交互,把已经发生的事通知用户,把正在发生的事交给用户处理,用一个词就是“观察者模式”。
当然,在语法上只有符合规则,怎么使用回调函数都可以

举个例子吧

C/C++ code


void ShutdownComputer()
{
//关机...
}


这种情况下,用户不能干预“关机”

C/C++ code

……
[/Quote]
缤纷冷泪 2012-07-01
  • 打赏
  • 举报
回复
我个人理解
回调函数更多的适用于和用户交互,把已经发生的事通知用户,把正在发生的事交给用户处理,用一个词就是“观察者模式”。
当然,在语法上只有符合规则,怎么使用回调函数都可以

举个例子吧

void ShutdownComputer()
{
//关机...
}

这种情况下,用户不能干预“关机”

typedef bool (* Ok) ();

Ok _ok; //全局变量

void Register(Ok ok) //注册回调函数
{
_ok=ok;
}
void ShutdownComputer()
{
if( _ok() )
{
//关机...
}
else
{
//取消关机
}
}

bool func()
{
bool b;
//...一系列判断
if ( b /*符合关机条件*/)
{
return true;
}
else
{
return false;
}
}

这种情况,由用户决定该做什么,用户可以干预“关机”
zyb_debug 2012-07-01
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 的回复:]

定义全局函数指针数组,

家一个void* 数组保存参数,

不ok??

另外:问一下,对于全局变量,如果没有用extern修饰, 生命期也是 和exe的生命期一样

所以用全局绝对可以随时去访问到 这2个数组的内容的。

[/Quote]
这个牵扯到面向对象的问题。CCommu 它的功能就是封装一个通用的函数指针调用的。
如果都用全局变量,这个文件一个全局,那个文件另外一个全局。等到你的文件有几百个文件的时候,首先,命名会遭到冲突,第二,变量名不好起。第三:维护成本很高,因为全局变量你不知道会被那些函数调用,而用类封装一下,基本就只有这个类在用这些变量。。。

意见仅供参考。
zrdongjiao 2012-07-01
  • 打赏
  • 举报
回复
定义全局函数指针数组,

家一个void* 数组保存参数,

不ok??

另外:问一下,对于全局变量,如果没有用extern修饰, 生命期也是 和exe的生命期一样

所以用全局绝对可以随时去访问到 这2个数组的内容的。





[Quote=引用 2 楼 的回复:]
它代码的意思是,把某个函数指针保存到变量里面,等到合适的时候调用。
int reg_cb(cb_type type, cb_func func, void *args = NULL)//注册回调函数
{
if(type <= CB_BUYEQUIIP)
{
func_list[ type ] = func; //把回调函数的地址保存下来。。。
f……
[/Quote]

super_admi 2012-07-01
  • 打赏
  • 举报
回复
回调函数本身不复杂。并且,在前面的帖子里我也回复过,回调函数是个通用的概念,不局限于WINDOWS。

1.为什么要有回调函数。回调函数肯定是要完成一个任务,问题是,该任务并不是马上就要完成,并且,大多数时候,我们并不能确定要做该任务的时间段。只有满足某个条件的时候,回调函数才会被触发。
如果你知道“中断”这个概念,那么“回调”的概念就很好理解了。

2.为什么要设计复杂的类来做回调。虽然回调很简单,但使用回调的系统并不见得简单。很多时候,我们为了考虑到各种移植问题,代码重用问题,可扩展性问题,不得不去构建一些通用框架来实现我们的设计,这就是“变得复杂”的基本理由。你的思维层次不够,人家要考虑的方方面面,你是看不到的。
当然,并不一定变复杂了,就是好的,这和设计有关。
zrdongjiao 2012-07-01
  • 打赏
  • 举报
回复

我也这么觉得,

可是不少文章, 专门搞了几个类来使用函数指针。。

有必要吗?

搞了那么复杂




[Quote=引用 1 楼 的回复:]
回调函数就是一个函数指针的概念 没有什么神秘的
[/Quote]
zyb_debug 2012-07-01
  • 打赏
  • 举报
回复
它代码的意思是,把某个函数指针保存到变量里面,等到合适的时候调用。
int reg_cb(cb_type type, cb_func func, void *args = NULL)//注册回调函数
{
if(type <= CB_BUYEQUIIP)
{
func_list[ type ] = func; //把回调函数的地址保存下来。。。
func_args[type] = args; //把需要传给回调函数的参数保存下来
return 0;
}
}
wshn13 2012-07-01
  • 打赏
  • 举报
回复
回调函数就是一个函数指针的概念 没有什么神秘的
zrdongjiao 2012-07-01
  • 打赏
  • 举报
回复
它这个设计的不好, 在调用的时候,应该上,



通过模块类来调用,

CGame类注册即可。







[Quote=引用楼主 的回复:]
C# code

昨天问了个回调注册 的问题,大家都说,c++没有注册这个概念,是windows的。

找了篇博客 ,看了会,有的地方没有搞懂。

这是博客内容.



CGameStart中有个CCommu 类指针,CCommu 中有函数指针数组。

CGameStart 里定义了一些静态函数指针。 Init函数 然后把这些指针,赋值给CCommu 的成员函数指针
数……
[/Quote]
zrdongjiao 2012-07-01
  • 打赏
  • 举报
回复

动了,它吧

bool func()
{
bool b;
//...一系列判断
if ( b /*符合关机条件*/)
{
return true;
}
else
{
return false;
}
}

给用户实现,,,,



确实替代 回调函数的方式很多









[Quote=引用 7 楼 的回复:]
我个人理解
回调函数更多的适用于和用户交互,把已经发生的事通知用户,把正在发生的事交给用户处理,用一个词就是“观察者模式”。
当然,在语法上只有符合规则,怎么使用回调函数都可以

举个例子吧

C/C++ code


void ShutdownComputer()
{
//关机...
}


这种情况下,用户不能干预“关机”

C/C++ code

……
[/Quote]
缤纷冷泪 2012-07-01
  • 打赏
  • 举报
回复
用户的范围很广,在编程这一个层级,用户更多是程序员。回调函数就是程序员之间交互的一种手段而已

A写的函数给B用,B就是A的用户

更多的是A厂商生产的库发布给BCDEFG很多厂商,但是A厂商不可能在库中把BCDEFG厂商对某个事件处理的方法都事先写进库里面,只能提供一个对事件处理的接口(接口不一定是回调函数),怎么处理由BCDEFG厂商自己决定。这也就是“提供机制,不提供决策”。


如果,程序都是一个人设计的话,可不必使用回调函数,有多种技术手段能替代回调函数。
如果,程序是多个设计的话,可不必使用回调函数,有多种技术手段能替代回调函数。
使用什么技术手段,只用使用得法就好。


既然你说到windows中有SendMessage,想必你一定知道WNDPROC吧?


[Quote=引用 8 楼 的回复:]
貌似是高手,

高手,再问个事情,



把已经发生的事通知用户,把正在发生的事交给用户处理


已经发生了什么事情???

正在发生了什么事情?


程序最终给用户使用, 用户操作的只是一个界面程序。

我始终不懂, 所谓通知,如何通知的,

windows中有SendMessage,可以告诉某个窗口,






引用 7 楼 的回复:
……
[/Quote]

65,187

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧